useFormStateのStateをリセットする
ReactのuseFormState(useActionState)を使用している人向けの記事になります。
useFormStateについて
新規にリリースされるReactではuseActionState
に名前が変更されておりますが、現在の安定版ではuseFormStateになっています。
React標準のHooksですが現時点ではNext.jsのServer Actions
で使用する機会が多いと思います。(筆者もApp Routerで使用しています)
機能としては命名通りフォームの状態をサーバーと共有するためのHooksです。
使い方
定義は以下となっており、第一引数にFormAction、第二引数にStateを設定します。permalink?
は今回の説明とあまり関係ないので割愛します。
useFormState(action, initialState, permalink?)
問題
今回重要なのはこの第二引数のStateでした。
Server Actions
でサーバー側の処理が成功後にStateが成功状態になります。そのためフォーム送信成功後に画面遷移が走らないと、フォームの状態がいつまで残ってしまいます。
例えば今回問題となったのはダイヤログにForm機能があり、送信後にもダイヤログに送信成功後の状態が残ってしまうため、再度ダイヤログを表示すると成功状態が表示されてしまいました。
解決方法
useFormState
のState状態をリセットして上げればいいのですが、探してみましがとくにリセットするAPIが提供はされておりませんでした。
そのため解決方法としてコンポーネント自体を再マウントすることで初期化させることにします。
やり方としてはダイヤログが閉じたタイミングでcallbackを呼び出して、key
の値を更新するようにしました。
// UUIDを指定していますが、他の値であれば何でも大丈夫です
const [uuid, setUUID] = useState(crypto.randomUUID())
return (
<section className={`flex justify-end`}>
<Dialog
key={uuid}
initFormState={{ success: false }}
closeDialog={() => {
// ダイヤログを閉じた時にUUIDを変更することで、ダイヤログの状態をリセットする
setUUID(crypto.randomUUID())
}}
/>
</section>
)
補足
基本的にReactでは毎回再マウントさせるのはアンチパターンなので基本的には再描画させてください。ただし今回のようにuseFormState
の状態をリセットさせるやり方が思いつかなかったので、再マウントさせるやり方をしました。
Discussion