componentDidMount
のようなReactフックを使用するcomponentDidUpdate
、componentWillUnmount
、およびuseEffect
ライフサイクルフックに相当するものは何ですか?
componentDidMount
空の配列を2番目の引数としてuseEffect()
に渡し、マウント時にのみコールバックのみを実行します。
_function ComponentDidMount() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
console.log('componentDidMount');
}, []);
return (
<div>
<p>componentDidMount: {count} times</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
Click Me
</button>
</div>
);
}
ReactDOM.render(
<div>
<ComponentDidMount />
</div>,
document.querySelector("#app")
);
_
_<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
_
componentDidUpdate
componentDidUpdate()
は、更新が発生した直後に呼び出されます。このメソッドは、最初のレンダリングでは呼び出されません。 useEffect
は、最初のレンダリングを含むすべてのレンダリングで実行されます。したがって、componentDidUpdate
と厳密に同等なものが必要な場合は、useRef
を使用して、コンポーネントが一度マウントされたかどうかを判断する必要があります。さらに厳密にしたい場合は、useLayoutEffect()
を使用しますが、同時に起動します。ほとんどの場合、useEffect()
で十分です。
これは 答えはTholleに触発された であり、すべての功績は彼に帰属します。
_function ComponentDidUpdate() {
const [count, setCount] = React.useState(0);
const isFirstUpdate = React.useRef(true);
React.useEffect(() => {
if (isFirstUpdate.current) {
isFirstUpdate.current = false;
return;
}
console.log('componentDidUpdate');
});
return (
<div>
<p>componentDidUpdate: {count} times</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
Click Me
</button>
</div>
);
}
ReactDOM.render(
<ComponentDidUpdate />,
document.getElementById("app")
);
_
_<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
_
componentWillUnmount
UseEffectのコールバック引数でコールバックを返すと、アンマウントする前に呼び出されます。
_function ComponentWillUnmount() {
function ComponentWillUnmountInner(props) {
React.useEffect(() => {
return () => {
console.log('componentWillUnmount');
};
}, []);
return (
<div>
<p>componentWillUnmount</p>
</div>
);
}
const [count, setCount] = React.useState(0);
return (
<div>
{count % 2 === 0 ? (
<ComponentWillUnmountInner count={count} />
) : (
<p>No component</p>
)}
<button
onClick={() => {
setCount(count + 1);
}}
>
Click Me
</button>
</div>
);
}
ReactDOM.render(
<div>
<ComponentWillUnmount />
</div>,
document.querySelector("#app")
);
_
_<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
_
From React docs :
Reactクラスライフサイクルメソッドに精通している場合、useEffectフックはcomponentDidMount、componentDidUpdate、およびcomponentWillUnmountを組み合わせたものと考えることができます。
ということで彼らは意味する:
componentDidMountはuseEffect(callback, [])
のようなものです
componentDidUpdateはuseEffect(callback, [dep1, dep2, ...])
のようなものです-depsの配列はReactに伝えます: "変更したら、レンダリング後にコールバックを実行してください」。
componentDidMount + componentDidUpdateはuseEffect(callback)
のようなものです
componentWillUnmountは、コールバックから返された関数の一種です。
useEffect(() => {
/* some code */
return () => {
/* some code to run when rerender or unmount */
}
)
Dan Abramov の彼の blog のフレージングと、私自身のいくつかの追加の助けを借りて:
これらのフックを使用できますが、完全に同等ではありません。 componentDidMount
やcomponentDidUpdate
とは異なり、captureの小道具と状態になります。そのため、コールバック内でも、特定のレンダーのプロップと状態が表示されます(つまり、componentDidMount
で最初のプロップと状態が表示されます)。 「最新の」何かを見たい場合は、refに書き込むことができます。しかし、通常、コードを構造化するより簡単な方法があるため、必要はありません。 componentWillUnmount
に代わるものと想定される返された関数も、コンポーネントが再レンダリングされたり、コンポーネントがアンマウントされるたびに実行されるため、完全に同等ではありません。効果のメンタルモデルはコンポーネントのライフサイクルとは異なることに注意してください。正確な同等物を見つけようとすると、助け以上の混乱を招く可能性があります。生産性を高めるには、「効果を考える」必要があり、それらのメンタルモデルは、ライフサイクルイベントへの応答よりも同期の実装に近いものです。
Danのブログの例:
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
console.log(`You clicked ${count} times`);
}, 3000);
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
クラス実装を使用する場合:
componentDidUpdate() {
setTimeout(() => {
console.log(`You clicked ${this.state.count} times`);
}, 3000);
}
this.state.count
は常に、特定のレンダーに属するカウントではなく、latestカウントを指します。