React.ComponentとReact.PureComponentの違い
React.ComponentとReact.PureComponentの違い
主な違いは、shouldComponentUpdateの実装にあります。
- React.Componentは、shouldComponentUpdateを実装していないため、デフォルトでは常に再レンダリングされます。
- React.PureComponentは、shouldComponentUpdateを浅い比較で実装しています。つまり、propsとstateが前回と異なっていなければ再レンダリングされません。
PureComponentを使うべき場合
- コンポーネントのrender関数が、propsとstateに基づいて常に同じ結果を出力する場合
- コンポーネントのレンダリングがパフォーマンスに影響を与える場合
- コンポーネントのrender関数が、複雑な計算や外部APIへのアクセスなどを行う場合
- コンポーネントが常に最新の状態を表示する必要がある場合
例
// React.Component
class MyComponent extends React.Component {
render() {
return <h1>{this.props.title}</h1>;
}
}
// React.PureComponent
class MyPureComponent extends React.PureComponent {
render() {
return <h1>{this.props.title}</h1>;
}
}
上記の例では、MyComponentとMyPureComponentはどちらも同じようにタイトルを表示するコンポーネントです。しかし、MyPureComponentはshouldComponentUpdateを実装しているため、props.titleが前回と異なっていなければ再レンダリングされません。
React.ComponentとReact.PureComponentは、Reactでコンポーネントを作成するためのベースクラスです。PureComponentは、shouldComponentUpdateを実装することで、不要な再レンダリングを抑制し、パフォーマンスを向上させることができます。
// App.js
import React, { useState } from 'react';
const App = () => {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<p>カウント: {count}</p>
<button onClick={handleClick}>カウントを増やす</button>
<MyComponent count={count} />
<MyPureComponent count={count} />
</div>
);
};
// MyComponent.js
import React from 'react';
const MyComponent = ({ count }) => {
console.log('MyComponent rendered');
return (
<div>
<h1>MyComponent</h1>
<p>カウント: {count}</p>
</div>
);
};
// MyPureComponent.js
import React, { PureComponent } from 'react';
class MyPureComponent extends PureComponent {
console.log('MyPureComponent rendered');
render() {
const { count } = this.props;
return (
<div>
<h1>MyPureComponent</h1>
<p>カウント: {count}</p>
</div>
);
}
}
export default App;
このコードを実行すると、以下のようになります。
- 最初に、カウントは0です。
- "カウントを増やす"ボタンをクリックすると、カウントが1増えます。
- MyComponentは常に再レンダリングされます。
- MyPureComponentは、countが前回と異なっている場合のみ再レンダリングされます。
コンソールログ
MyComponent rendered
MyPureComponent rendered
MyComponent rendered
MyPureComponent rendered
MyComponent rendered
このように、MyPureComponentはshouldComponentUpdateを実装することで、不要な再レンダリングを抑制していることがわかります。
注意事項
- PureComponentは、propsとstateが浅い比較のみを行います。深い比較が必要な場合は、shouldComponentUpdateを独自に実装する必要があります。
- PureComponentは、子コンポーネントもPureComponentである場合にのみ、パフォーマンスの向上に効果があります。
React.PureComponent 以外の方法
class MyComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// propsとstateの深い比較を行う
return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
}
render() {
// ...
}
}
memo を使用する
memo は、コンポーネントとその props をラップし、不要な再レンダリングを抑制する HOC (Higher-Order Component) です。
const MyComponent = memo((props) => {
// ...
});
useCallback と useMemo を使用する
useCallback は、関数とその依存関係をキャッシュし、不要な再レンダリングを抑制する Hook です。useMemo は、値とその依存関係をキャッシュし、不要な再レンダリングを抑制する Hook です。
const MyComponent = () => {
const handleClick = useCallback(() => {
// ...
}, []);
const memoizedValue = useMemo(() => {
// 計算コストの高い処理
return ...;
}, []);
// ...
};
PureRenderMixin は、React 15.x 以前で使用されていた mixin で、shouldComponentUpdate を浅い比較で実装します。
var MyComponent = React.createClass({
mixins: [PureRenderMixin],
render() {
// ...
}
});
reactjs state