Pitfall
We recommend defining components as functions instead of classes.See how to migrate.
PureComponent is similar toComponent but it skips re-renders for same props and state. Class components are still supported by React, but we don’t recommend using them in new code.
class GreetingextendsPureComponent{
render(){
return<h1>Hello,{this.props.name}!</h1>;
}
}Reference
PureComponent
To skip re-rendering a class component for same props and state, extendPureComponent instead ofComponent:
import{PureComponent}from'react';
class GreetingextendsPureComponent{
render(){
return<h1>Hello,{this.props.name}!</h1>;
}
}PureComponent is a subclass ofComponent and supportsall theComponent APIs. ExtendingPureComponent is equivalent to defining a customshouldComponentUpdate method that shallowly compares props and state.
Usage
Skipping unnecessary re-renders for class components
React normally re-renders a component whenever its parent re-renders. As an optimization, you can create a component that React will not re-render when its parent re-renders so long as its new props and state are the same as the old props and state.Class components can opt into this behavior by extendingPureComponent:
class GreetingextendsPureComponent{
render(){
return<h1>Hello,{this.props.name}!</h1>;
}
}A React component should always havepure rendering logic. This means that it must return the same output if its props, state, and context haven’t changed. By usingPureComponent, you are telling React that your component complies with this requirement, so React doesn’t need to re-render as long as its props and state haven’t changed. However, your component will still re-render if a context that it’s using changes.
In this example, notice that theGreeting component re-renders whenevername is changed (because that’s one of its props), but not whenaddress is changed (because it’s not passed toGreeting as a prop):
import{PureComponent,useState}from'react';class GreetingextendsPureComponent{render(){console.log("Greeting was rendered at",newDate().toLocaleTimeString());return<h3>Hello{this.props.name &&', '}{this.props.name}!</h3>;}}exportdefaultfunctionMyApp(){const[name,setName] =useState('');const[address,setAddress] =useState('');return(<><label> Name{': '}<inputvalue={name}onChange={e=>setName(e.target.value)}/></label><label> Address{': '}<inputvalue={address}onChange={e=>setAddress(e.target.value)}/></label><Greetingname={name}/></>);}
Pitfall
We recommend defining components as functions instead of classes.See how to migrate.
Alternatives
Migrating from aPureComponent class component to a function
We recommend using function components instead ofclass components in new code. If you have some existing class components usingPureComponent, here is how you can convert them. This is the original code:
import{PureComponent,useState}from'react';class GreetingextendsPureComponent{render(){console.log("Greeting was rendered at",newDate().toLocaleTimeString());return<h3>Hello{this.props.name &&', '}{this.props.name}!</h3>;}}exportdefaultfunctionMyApp(){const[name,setName] =useState('');const[address,setAddress] =useState('');return(<><label> Name{': '}<inputvalue={name}onChange={e=>setName(e.target.value)}/></label><label> Address{': '}<inputvalue={address}onChange={e=>setAddress(e.target.value)}/></label><Greetingname={name}/></>);}
When youconvert this component from a class to a function, wrap it inmemo:
import{memo,useState}from'react';constGreeting =memo(functionGreeting({name}){console.log("Greeting was rendered at",newDate().toLocaleTimeString());return<h3>Hello{name &&', '}{name}!</h3>;});exportdefaultfunctionMyApp(){const[name,setName] =useState('');const[address,setAddress] =useState('');return(<><label> Name{': '}<inputvalue={name}onChange={e=>setName(e.target.value)}/></label><label> Address{': '}<inputvalue={address}onChange={e=>setAddress(e.target.value)}/></label><Greetingname={name}/></>);}
Note
UnlikePureComponent,memo does not compare the new and the old state. In function components, calling theset function with the same statealready prevents re-renders by default, even withoutmemo.