🌊
Remix + conformでaction実行後にrevalidateされたloaderの値でFormを更新するための肝
背景
loaderでorderByを使って並び替えを行なっている場合、actionを使って保存処理を行った後、Formも並び替えられて欲しかった。
しかし、下記の対応をするまでは、値の更新はできてもdefaultValueは保持されるため、並べ替えは反映できなかった。
結論
idにloaderから取得したdataのJSONを入れ込むとidが都度変更されるため、再度defaultValueが設定され、並び替えがFormにも反映される。
例
import { useLoaderData, useActionData, useSubmit, Form } from '@remix-run/react';
import { useForm, getInputProps } from '@conform-to/react';
export default function TodoList() {
const data = useLoaderData<typeof loader>();
const actionData = useActionData<typeof action>();
const submit = useSubmit();
const [form, fields] = useForm({
id: `todo-form-${JSON.stringify(data.todos)}`,
onValidate({ formData }) {
return parseWithZod(formData, { schema: todoSchema });
},
defaultValue: { todos: data.todos },
lastResult: actionData?.result,
});
const todoFields = fields.todos.getFieldList();
return (
<div>
<h1>TODOリスト</h1>
<Form method="post" {...form.props}>
<ul>
{todoFields.map((todo, index) => (
<li key={index}>
<input type="text" {...getInputProps(todo.task, { type: 'text' })} />
<input type="checkbox" {...getInputProps(todo.completed, { type: 'checkbox' })} />
<button
{...form.remove.getButtonProps({
name: fields.careerHistories.name,
index,
})}
onClick={() => {
if (confirm('削除してもよろしいですか?')) {
submit({ id: todo.id.value }, { method: 'delete' });
}
}}
>
削除
</button>
</li>
))}
</ul>
<button type="submit">保存</button>
</Form>
<button {...form.insert.getButtonProps({
name: fields.todos.name,
})}>
新しいTODOを追加
</button>
</div>
);
}
あとがき
メモがてら急ぎ足で書いたので雑ですが、誰かの助けになれば幸いです。
Discussion