のような React フックを使用する、、、およびライフサイクル フックcomponentDidMount
にcomponentDidUpdate
相当するものは何 ですか?componentWillUnmount
useEffect
4 に答える
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/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/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/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
componentWillUnmount
useEffect の callback 引数でコールバックを返すと、アンマウントする前に呼び出されます。
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/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
React ドキュメントから:
React クラスのライフサイクル メソッドに精通している場合は、useEffect フックを componentDidMount、componentDidUpdate、および componentWillUnmount を組み合わせたものと考えることができます。
そのことわざによって、彼らは次のことを意味します。
componentDidMountは一種のuseEffect(callback, [])
componentDidUpdateは一種のものですuseEffect(callback, [dep1, dep2, ...])
- deps の配列は Reactに「deps の 1 つが変更された場合、レンダリング後にコールバックを実行します」と伝えます。
componentDidMount + componentDidUpdateは一種のuseEffect(callback)
componentWillUnmountは、コールバックから返された関数の一種です。
useEffect(() => {
/* some code */
return () => {
/* some code to run when rerender or unmount */
}
)
Dan Abramovのブログからの言い回しと、私自身のいくつかの追加の助けを借りて:
これらのフックを使用できますが、完全に同等ではありません。と とは異なりcomponentDidMount
、小道具と状態componentDidUpdate
をキャプチャします。したがって、コールバック内でも、特定のレンダリングの小道具と状態が表示されます (つまりcomponentDidMount
、最初の小道具と状態で)。「最新」のものを見たい場合は、それを ref に書き込むことができます。しかし、通常、コードを構造化するより簡単な方法があり、その必要はありません。に代わると思われる返された関数componentWillUnmount
コンポーネントが再レンダリングされるたびに、およびコンポーネントがアンマウントされるときに関数が実行されるため、これも完全に同等ではありません。効果のメンタル モデルはコンポーネントのライフサイクルとは異なることに注意してください。正確に同等のものを見つけようとすると、助けになるどころか混乱する可能性があります。生産性を高めるには、「効果を考える」必要があり、彼らのメンタル モデルは、ライフサイクル イベントへの対応よりも同期の実装に近いものです。
ダンのブログからの例:
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
特定のレンダリングに属するものではなく、常に最新のカウントを指します。
以下はReact Hooks FAQからの良い要約で、クラスのライフサイクル メソッドに相当するフックをリストしています。
constructor
: 関数コンポーネントにはコンストラクターは必要ありません。呼び出しで状態を初期化できますuseState
。初期状態の計算にコストがかかる場合は、関数を に渡すことができますuseState
。
getDerivedStateFromProps
:代わりに、レンダリング中に更新をスケジュールします。
shouldComponentUpdate
:以下のReact.memo を参照してください。
render
: 機能部品本体です。
componentDidMount
,componentDidUpdate
,componentWillUnmount
:useEffect
フックは、これらのすべての組み合わせを表現できます (あまり 一般的でないケースを含む)。
componentDidCatch
andgetDerivedStateFromError
:これらのメソッドに相当するフックはまだありませんが、すぐに追加される予定です。
componentDidMount
useEffect(() => { /*effect code*/ }, []);
[]
マウント時に一度だけ効果を実行します。通常、依存関係を指定する方が適切です。と同じレイアウト タイミングにするcomponentDidMount
場合は、 を参照してくださいuseLayoutEffect
(ほとんどの場合は必要ありません)。
componentWillUnmount
useEffect(() => { /*effect code*/ ; return ()=> { /*cleanup code*/ } }, [deps]);
componentWillUnmount
cleanupの効果に対応します。
componentDidUpdate
const mounted = useRef();
useEffect(() => {
if (!mounted.current) mounted.current = true;
else {
// ... on componentDidUpdate
}
});
と同じレイアウト タイミングにするcomponentDidUpdate
場合は、 を参照してくださいuseLayoutEffect
(ほとんどの場合は必要ありません)。同等のフックの詳細については、この投稿も参照してください。componentDidUpdate