redux-form の changeを用いた特定のフォームの値をリセットする方法
背景
実務でredux-formを用いた特定のフォームの値を削除するフォームを作成する場面がありました。
redux-formにはフォームの値をリセットする reset というpropsがあります。
しかし、redux-formの「reset」というpropsを使用してしまうと、redux-formで使用しているフォーム全体の値がリセットしてしまうため、特定のフォームの値をリセットすることができませんでした。
そこで今回は、redux-formで特定のフォームの値をリセットする方法を記事にまとめたので、特定のフォームの値をリセットしたいといった方の参考になれば幸いです。
結論
特定のフォームの値をリセットするには、redux-formのprops 「change」を使用し、 第三引数に「’ ’」を設定すること
解説
redux-formのprops 「change」の使用方法は以下のとおりです。
change('第一引数(form名)', '第二引数(field名)', '第三引数(変更したい値)')
changeはredux-formの関数propsであり、第一引数にはform名、第二引数にはfield名、第三引数には変更したい値を設定・実行してあげることでfieldが持つ値を変更することができます。
使用場面は、以下の通りです。
- フォームの初期値を設定する必要がある場合
- フォームの値を動的に更新する必要がある場合
- フィールドの値を変更する必要がある場合
今回は、特定のフィールドの値をリセットしたいので、第三引数に「’ ’」を設定することでうまくいきました。
作成したサンプルコードは以下の通りです。
今回、入力フォームを4つ用意し、職業を入力させるフォームのところに対して、値をリセットする削除ボタンを作成しました。
また、送信ボタンを押下することで、入力フォームに入力したデータがアラートメッセージがに表示する仕組みとなっています。
App.jsx
// components
import NameForm from './components/user/NameForm';
// function
import showResults from "./func/showResults";
function App() {
return (
<div className="App">
<br></br>
<br></br>
<NameForm onSubmit={showResults} />
<br></br>
<br></br>
</div>
);
}
export default App;
showResults.js(onSubmit実行時にアラートで結果を表示する関数)
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
export default (async function showResults(values) {
// 入力値があるかどうか判定
function isEmpty(obj) {
return !Object.keys(obj).length
}
if (isEmpty(values)) {
alert('値がありません。何か入力してください。')
} else {
await sleep(500);
window.alert(`あなたは以下のデータを送信しました。:\n\n${JSON.stringify(values, null, 2)}`);
}
});
NameForm.jsx(入力フォームのcomponent)
import React from 'react'
import { reduxForm, Field, change } from 'redux-form'
// component
import renderField from '../common/renderField'
const NameForm = ({ handleSubmit, dispatch }) => {
**// 「職業入力フォームのみ削除」ボタン押下時に実行
const jobFormReset = (e) => {
// onSubmitのデフォルト処理をキャンセル
e.preventDefault()
// 職業入力フォームのみ削除
dispatch(change('changeform', 'job', ''))
}**
return (
<form onSubmit={handleSubmit}>
<Field name="name" component={renderField} label="名前" />
<Field name="sex" component={renderField} label="性別" />
<Field name="age" component={renderField} label="年齢" />
<Field name="job" component={renderField} label="職業" />
<button type="submit">送信</button>
<button onClick={(e) => jobFormReset(e)}>職業入力フォームのみ削除</button>
</form>
)
}
export default reduxForm({
form: 'changeform',
validate
})(NameForm)
今回注目していただきたいのは、下記の部分です。
**// 「職業入力フォームのみ削除」ボタン押下時に実行
const jobFormReset = (e) => {
// onSubmitのデフォルト処理をキャンセル
e.preventDefault()
// 職業入力フォームのみ削除
dispatch(change('changeform', 'job', ''))
}**
「職業入力フォームのみ削除」ボタン押下時に、jobFormResetという関数を実行させ、dispatchの中でchangeを実行しています。
この時 dispatch を用いる理由は、redux-form がReduxストアを使用してフォームの状態を管理しているためです。
redux-form は、フォームの状態が変更されるたびに、Reduxストア内の状態を更新し、同期します。
dispatch は、Reduxアプリケーション内でアクションを発行するために使用される関数です。
アクションは、Reduxストアに送信され、それに応じて状態が更新されます。
change関数は、Reduxストアにフィールドの変更アクションを送信するために dispatch を使用します。
つまり、change 関数がReduxストアの状態を変更するには、dispatch 関数を使用する必要があります。
今回は、changeの第三引数に「’ ’」という空の値を設定することで、change実行時にjobフィールドの値をリセットするようにしました。
このようにすることで、全体のフィールドの値をリセットせず、特定のフィールドの値をリセット・初期化することができます。
まとめ
今回はredux-formを使用し、特定のフォームの値をリセット・初期化する方法をご紹介しました。
今回の実装を行うためにredux-formのchangeというpropsの特徴と使い方を知りました。
redux-formのchangeを使用する機会は今後も増えていくと思うので、うまく使いこなせるようにしていきたいです。
今回の記事が、redux-formを使用している方の参考になれば幸いです。
Discussion