🦁
useState / useRef / useFormの初期値にPropsの値を使っている場合の注意点
こまりごと
useStateやuseRefの初期値はコンポーネントのマウント時にしか設定されません。
そのため、例えば下記のようにstateの初期値にPropsを使っている場合、Propsが更新されてもstateが更新されることはありません。
const Component: React.FC<Data> = ({ data }) => {
const [state, setState] = useState(data)
...
return (
<>
...
</>
)
}
解決法
よく見るやりかた
PropsをuseEffectの依存変数に加えることでPropsの更新によりstateを更新できます。
const Component: React.FC<Data> = ({ data }) => {
const [state, setState] = useState(data)
useEffect(()=>{
setState(data)
},[data])
...
return (
<>
...
</>
)
}
ベターなやりかた
上記のようにuseEffectを使うと無駄な再描画が発生するため、下記のやり方がスマートです。
コンポーネントのkey属性が変更された場合、コンポーネントは初期化されます。
const ParentComponent: React.FC<{}> = () => {
const data = useData()
return <Component key={JSON.stringify(data)} data={data} />
}
const Component: React.FC<Data> = ({ data }) => {
const [state, setState] = useState(data)
...
return (
<>
...
</>
)
}
useRefやuseFormも同様
useRef
やReact-Hook-FormのuseForm
でstateを管理している場合も同様です。
特にuseRef
を使っている場合、refをuseEffectの依存変数に加えることはできないため、コンポーネントをマウントし直す必要があります。
参考
Discussion