PureComponent
PureComponent
es parecido a Component
pero se salta los rerenderizados para las mismas props y estado. Los componentes de clase todavía son compatibles con React, pero no recomendamos usarlos en código nuevo.
class Greeting extends PureComponent {
render() {
return <h1>¡Hola, {this.props.name}!</h1>;
}
}
Referencia
PureComponent
Para omitir volver a renderizar un componente de clase para las mismas props y estado, extiende PureComponent
en lugar de Component
:
import { PureComponent } from 'react';
class Greeting extends PureComponent {
render() {
return <h1>¡Hola, {this.props.name}!</h1>;
}
}
PureComponent
es una subclase de Component
y admite todas las API de Component
. Extender PureComponent
es equivalente a definir un método personalizado shouldComponentUpdate
que compara superficialmente las props y el estado.
Uso
Omitir renderizados innecesarios para componentes de clase
React normalmente rerenderiza un componente cada vez que su padre se rerenderiza. Como optimización, puedes crear un componente que React no rerenderizará cuando su padre se renderice, siempre que sus props y estado nuevos sean los mismos que los anteriores. Los componentes de clase pueden optar por este comportamiento extendiendo PureComponent
:
class Greeting extends PureComponent {
render() {
return <h1>¡Hola, {this.props.name}!</h1>;
}
}
Un componente de React siempre debe tener lógica de renderizado pura. Esto significa que debe devolver el mismo resultado si sus props, estado y contexto no han cambiado. Al usar PureComponent
, le estás diciendo a React que tu componente cumple con este requisito, por lo que React no necesita volver a renderizar siempre que sus props y estado no hayan cambiado. Sin embargo, tu componente aún se rerenderizará si cambia un contexto que esté usando.
En este ejemplo, observa que el componente Greeting
se vuelve a renderizar cada vez que se cambia name
(porque es una de sus props), pero no cuando se cambia address
(porque no se pasa a Greeting
como prop):
import { PureComponent, useState } from 'react'; class Greeting extends PureComponent { render() { console.log("Greeting se renderizó a las", new Date().toLocaleTimeString()); return <h3>Hola{this.props.name && ', '}{this.props.name}!</h3>; } } export default function MyApp() { const [name, setName] = useState(''); const [address, setAddress] = useState(''); return ( <> <label> Nombre{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Dirección{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }
Alternativas
Migración de un componente de clase PureComponent
a una función
Recomendamos usar componentes de función en lugar de componentes de clase en código nuevo. Si tienes algunos componentes de clase existentes que usan PureComponent
, te mostramos como puedes convertirlos. Este es el código original:
import { PureComponent, useState } from 'react'; class Greeting extends PureComponent { render() { console.log("Greeting se renderizó a las", new Date().toLocaleTimeString()); return <h3>¡Hola{this.props.name && ', '}{this.props.name}!</h3>; } } export default function MyApp() { const [name, setName] = useState(''); const [address, setAddress] = useState(''); return ( <> <label> Nombre{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Dirección{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }
Al convertir este componente de una clase a una función, envuélvelo en memo
:
import { memo, useState } from 'react'; const Greeting = memo(function Greeting({ name }) { console.log("Greeting se renderizó a las", new Date().toLocaleTimeString()); return <h3>¡Hola{name && ', '}{name}!</h3>; }); export default function MyApp() { const [name, setName] = useState(''); const [address, setAddress] = useState(''); return ( <> <label> Nombre{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Dirección{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }