🥑
React useCallbackの内部ソースコードを読んでみました
コード
import { useCallback, useState } from 'react';
const App = () => {
const [dataInvolved, setDataInvolved] = useState(1)
const [dataNotInvolved, setDataNotInvolved] = useState(1)
const nums = useCallback(() => dataInvolved * dataInvolved, [dataInvolved])
const handleClick = () => {
setDataInvolved(d => d + 1)
}
const handleClick2 = () => {
setDataNotInvolved(d => d + 1)
}
return (
<div className='container'>
<button onClick={handleClick}>click</button>
<button onClick={handleClick2}>click2</button>
<p>count:{nums()}</p>
</div>
);
};
export default App
動作
- clickボタンをクリックした時に、count:{値変化あり}
- click2ボタンをクリックした時に、count:{値変化ありません}
流れ説明
mount時
- App関数を実行、以下の行を実行します
const nums = useCallback(() => dataInvolved * dataInvolved, [dataInvolved])
- react内部のuseCallbackを実行します
- mountCallbackを実行します
- Hookオブジェクト作成します
- 作成したオブジェクトをAppのFiberNodeに保存します
- 関数とdepsを作成したhookオブジェクトに保存します
7.callback関数をAppに返します
- App関数をcallback関数をもって、実行、最新のReact.Elementを作成し、Fiberツリー構築へ
- dom操作して、画面に描画させます
update時
- App関数を実行、以下の行を実行します(mount時と同じです)
- react内部のuseCallbackを実行します(mount時と同じです)
- updateCallbackを実行します
- Hookオブジェクト作成します(mount時と同じです)
- 作成したオブジェクトをAppのFiberNodeに保存します(mount時と同じです)
- AppのFiberNodeに保存してcallbackとdepsを取り出します
- 今渡しているdepsとAppのFiberNodeに保存されたdepsとshallow equalします
8-1. 7の結果はtrueの場合は、記憶したcallbackを返します
8-2. 7の結果はfalseの場合は、記憶を更新して、渡されたcallback関数をAppに返します。
- App関数をcallback関数をもって、実行、最新のReact.Elementを作成し、Fiberツリー構築へ
- 更新がある場合、dom操作して、画面に描画させます
メモリ図
説明動画
Discussion