Open3

「0を0にする」でも再レンダーされちゃうのなんで?

Yug (やぐ)Yug (やぐ)

なぜこれが無限ループして永遠にrenderが出力されてしまうんだ?という疑問。
Object.is(0, 0)はtrue->つまり値が変わっていないと認識される->renderはスキップされる
のはずでは...?

export default function App() {
    const [num, setNum] = useState(0);
    setNum(0);
    console.log('render');
}

以下のようにイベントハンドラ内にセッターを移すと無限ループは回避できるけれども。

export default function App() {
    const [num, setNum] = useState(0);
    console.log('render');

    return <button onClick={() => setNum(0)}>ボタン</button>;
}
Yug (やぐ)Yug (やぐ)

わからんなぁ...。コンポーネントのトップレベルで、つまりレンダー中にsetterを呼び出すのは良くないよ、みたいな認識?はありそうだなぁとは思うけど、「でもなんで?」状態。

Yug (やぐ)Yug (やぐ)

useStateだけでなくuseEffectでも同様の事象が発生した。

export default function App() {
    const [val, setVal] = useState(0);
    console.log('valは', val);

    useEffect(() => {
        console.log('effectのvalは', val);
        setVal(1);
    }, [val]);

    return (
        <>
            val: {val}
        </>
    )
}

これで結果は↓のようになる。最後に1を1にsetするという段階でrenderは無視されるはずなのにrenderが発火して再度2回コンソール出力されてる...。