Open6
jotaiの中身を読む
一番単純な下記のようなケースで何が起こるか見る
import { atom } from "jotai";
const countAtom = atom(0);
const Counter = () => {
const [count, setCount] = useAtom(countAtom);
return (
<>
<div>{count}</div>
<button onClick={() => setCount(count + 1)}>one up</button>
</>
);
};
atomは、主にread
とwrite
をプロパティとして持つオブジェクト。
read
とwrite
は、それぞれ値を読み書きするシンプルな処理だが、get
やset
の関数を引数に取る形になっている
Reactコンポーネントの中で呼ばれるuseAtom
は、useAtomValue
とuseSetAtom
の糖衣構文のような感じで、実際の処理はuseAtomValue
とuseSetAtom
で行っている。
まずはuseAtomValue
の方を見てみる
useAtomValue
では、下記処理を行っている
- jotaiの状態を保存しておくコアである、
store
を取得する。 - atomのvalueを取得して返す
- atomの変更を監視し、変更があったらコンポーネントを再レンダリングする
storeの処理を見ていく
コンポーネント内でuseAtomValue
が呼ばれるとstoreが作られるが、この実体は下記のdefaultStore
変数。
これは、get, set, subの3つの関数のプロパティを持つオブジェクト。
- get
- atomを引数に取り、そのvalueを返す
- https://github.com/pmndrs/jotai/blob/main/src/vanilla/store.ts#L404
- set:
- atomと、そのatomにsetする値を引数に取り、atomに値をsetする
- https://github.com/pmndrs/jotai/blob/main/src/vanilla/store.ts#LL474C3-L474C3
- sub:
- atomと、コールバック関数を引数に取り、atomの値が変化した時などにコールバック(listener)を実行できるようにする
- https://github.com/pmndrs/jotai/blob/main/src/vanilla/store.ts#L621
- listenerは、
mounted
という変数のl
というフィールドに格納され、flushPending
という関数が実行された時に呼ばれる。