PureComponent
PureComponent
é similar a Component
, mas ele pula as re-renderizações para as mesmas props e state. Componentes de classe ainda são suportados pelo React, mas não recomendamos usá-los em código novo.
class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
Referência
PureComponent
Para pular a re-renderização de um componente de classe para as mesmas props e state, estenda PureComponent
em vez de Component
:
import { PureComponent } from 'react';
class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
PureComponent
é uma subclasse de Component
e suporta todas as APIs de Component
. Estender PureComponent
é equivalente a definir um método shouldComponentUpdate
customizado que compara superficialmente as props e o state.
Uso
Pulando re-renderizações desnecessárias para componentes de classe
O React normalmente re-renderiza um componente sempre que seu pai re-renderiza. Como uma otimização, você pode criar um componente que o React não re-renderizará quando seu pai re-renderizar, desde que suas novas props e state sejam as mesmas das props e state antigas. Componentes de classe podem optar por este comportamento estendendo PureComponent
:
class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
Um componente React sempre deve ter lógica de renderização pura. Isso significa que deve retornar a mesma saída se suas props, state e contexto não mudaram. Ao usar PureComponent
, você está dizendo ao React que seu componente está em conformidade com esse requisito, portanto, o React não precisa re-renderizar, desde que suas props e o state não tenham mudado. No entanto, seu componente ainda será re-renderizado se um contexto que ele estiver usando mudar.
Neste exemplo, observe que o componente Greeting
re-renderiza sempre que name
é alterado (porque essa é uma de suas props), mas não quando address
é alterado (porque não é passado para Greeting
como uma 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> Name{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Address{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }
Alternativas
Migrando de um componente de classe PureComponent
para uma função
Recomendamos o uso de componentes de função em vez de componentes de classe em código novo. Se você tiver alguns componentes de classe existentes usando PureComponent
, aqui está como você pode convertê-los. Este é o código original:
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> Name{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Address{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }
Quando você converte este componente de uma classe para uma função, encapsule-o em 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> Name{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Address{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }