PureComponent
PureComponent è simile a Component ma salta le ri-renderizzazioni quando props e state sono gli stessi. I componenti classe sono ancora supportati da React, ma non consigliamo di usarli nel codice nuovo.
class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}Reference
PureComponent
Per saltare la ri-renderizzazione di un componente classe quando props e state sono gli stessi, estendi PureComponent invece di Component:
import { PureComponent } from 'react';
class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}PureComponent è una sottoclasse di Component e supporta tutte le API di Component. Estendere PureComponent equivale a definire un metodo shouldComponentUpdate personalizzato che confronta superficialmente props e state.
Usage
Saltare ri-renderizzazioni non necessarie per i componenti classe
Di norma React ri-renderizza un componente ogni volta che il genitore viene ri-renderizzato. Come ottimizzazione, puoi creare un componente che React non ri-renderizzerà quando il genitore viene ri-renderizzato, purché le nuove props e lo state siano uguali alle vecchie props e allo state precedente. I componenti classe possono adottare questo comportamento estendendo PureComponent:
class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}Un componente React dovrebbe sempre avere logica di renderizzazione pura. Ciò significa che deve restituire lo stesso output se props, state e context non sono cambiati. Usando PureComponent, stai dicendo a React che il tuo componente rispetta questo requisito, quindi React non ha bisogno di ri-renderizzarlo finché props e state non sono cambiati. Tuttavia, il tuo componente verrà comunque ri-renderizzato se cambia un context che sta usando.
In questo esempio, nota che il componente Greeting viene ri-renderizzato ogni volta che cambia name (perché è una delle sue props), ma non quando cambia address (perché non viene passato a Greeting come prop):
import { PureComponent, useState } from 'react'; class Greeting extends PureComponent { render() { console.log("Greeting was rendered at", new Date().toLocaleTimeString()); return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>; } } export default function MyApp() { const [name, setName] = useState(''); const [address, setAddress] = useState(''); return ( <> <label> Nome{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Indirizzo{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }
Alternatives
Migrare da un componente classe PureComponent a una funzione
Nel codice nuovo consigliamo di usare componenti funzione al posto dei componenti classe. Se hai componenti classe esistenti che usano PureComponent, ecco come convertirli. Questo è il codice originale:
import { PureComponent, useState } from 'react'; class Greeting extends PureComponent { render() { console.log("Greeting was rendered at", new Date().toLocaleTimeString()); return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>; } } export default function MyApp() { const [name, setName] = useState(''); const [address, setAddress] = useState(''); return ( <> <label> Nome{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Indirizzo{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }
Quando converti questo componente da classe a funzione, avvolgilo in memo:
import { memo, useState } from 'react'; const Greeting = memo(function Greeting({ name }) { console.log("Greeting was rendered at", new Date().toLocaleTimeString()); return <h3>Hello{name && ', '}{name}!</h3>; }); export default function MyApp() { const [name, setName] = useState(''); const [address, setAddress] = useState(''); return ( <> <label> Nome{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Indirizzo{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }