PureComponent
PureComponent は Componentに似ていますが、同じ props と state の場合は再レンダリングをスキップします。クラスコンポーネントはReactでまだサポートされていますが、新しいコードでは使用しないことをお勧めします。
class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}リファレンス
PureComponent
同じ props と state に対してクラスコンポーネントの再レンダリングをスキップするには、Componentの代わりにPureComponentを拡張します。
import { PureComponent } from 'react';
class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}PureComponent はComponentのサブクラスであり、すべてのComponent APIをサポートしています。PureComponentを拡張することは、props と state を浅く比較するカスタムshouldComponentUpdateメソッドを定義することと同じです。
使用方法
クラスコンポーネントの不要な再レンダリングをスキップする
React は通常、親が再レンダリングされるたびにコンポーネントを再レンダリングします。最適化として、新しい props と state が古い props と state と同じである限り、親が再レンダリングされても React が再レンダリングしないコンポーネントを作成できます。クラスコンポーネントは、PureComponent を拡張することで、この動作を選択できます。
class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}Reactコンポーネントは、常に純粋なレンダリングロジックを持つ必要があります。これは、props、state、およびコンテキストが変更されていない場合、同じ出力を返さなければならないことを意味します。PureComponentを使用することにより、コンポーネントがこの要件に準拠していることを React に伝えるため、props と state が変更されていない限り、React は再レンダリングする必要がありません。ただし、使用しているコンテキストが変更された場合、コンポーネントは引き続き再レンダリングされます。
この例では、Greeting コンポーネントは name が変更されるたびに再レンダリングされます(それがpropsの一つであるため)。しかし、address が変更されても再レンダリングされません(Greeting にpropsとして渡されていないため)。
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} /> </> ); }
代替手段
PureComponent クラスコンポーネントから関数コンポーネントへの移行
新しいコードでは、クラスコンポーネントの代わりに、関数コンポーネントを使用することをお勧めします。PureComponent を使用している既存のクラスコンポーネントがある場合は、次のように変換できます。これが元のコードです。
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} /> </> ); }
このコンポーネントをクラスから関数に変換する場合は、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} /> </> ); }