Reduxストアに「todos」の配列が含まれている単純なtodoアプリがあります。私の「Todo」コンポーネントは、ストア内のすべての「todo」にマップされ、redux-formsv6を使用する「TodoForm」コンポーネントをレンダリングします。
現在のように、すべての「todo」は同じフォーム名/キーを共有しているため、「title」フィールドに何かを入力するたびに、すべての「todo」の「title」が変更されます。一意のフィールド名を使用することで回避策を見つけましたが、アプリが大きくなるにつれて物事が複雑になりすぎるのではないかと心配しています。他のフォームに干渉することなくすべてのフィールドに同じ名前を付けることができるように、一意のフォーム名を使用することをお勧めします。
(TodoForm1、TodoForm2、TodoForm3はすべて、「title1」、「title2」、「title3」フィールドを含むTodoFormの代わりに、一意の「title」フィールドを持つことができます)。
TodoFormの小道具にアクセスして、各フォームのキーをコンポーネントの一意のIDとして設定できるようにしましたが、コンポーネントが小道具を早く受け取るようには見えません。
また、乱数を吐き出す即時呼び出し関数を作成し、その番号をフォームの名前として使用しようとしましたが、それも機能しませんでした。
すべてのToDoをマッピングし、一意のフォームキーを使用してv6 reduxフォームをレンダリングするにはどうすればよいですか?
これがアプリ、コンソール、reduxdevtoolsの写真です。 3つの「todo」がありますが、それらすべてを接続するフォームはtodo-926だけです。ただし、各フォームキーは、すぐに呼び出される関数でランダムに生成されるはずです。
HomePageMainSection.index.js
renderTodos(todo) {
if (!todo) {
return <div>No Todos</div>;
}
return (
<div key={todo.get('id')}>
<Todo
todo={todo}
updateTodo={this.props.updateTodo}
deleteTodo={this.props.deleteTodo}
/>
</div>
);
}
render() {
if (!this.props.todos) {
return <div>No Todos</div>;
}
return (
<div className={styles.homePageMainSection}>
<h1>Hey I'm the Main Section</h1>
<div>
{this.props.todos.get('todos').map(this.renderTodos)}
</div>
</div>
);
}
Todo.index.js:
renderTodo() {
if (this.state.editMode) {
return (
<TodoForm
todo={this.props.todo} changeTodoEditMode={this.changeTodoEditMode}
updateTodo={this.props.updateTodo}
/>
);
}
return (
<div className={styles.Todo} onClick={this.changeTodoEditMode}>
<div className="card card-block">
<h4 className="card-title">{this.props.todo.get('author')}</h4>
<p className="card-text">{this.props.todo.get('title')}</p>
<i
className={`${styles.deleteIcon} btn btn-danger fa fa-times`}
onClick={this.deleteTodo}
></i>
</div>
</div>
);
}
render() {
return (
<div className="col-xs-6 col-sm-4">
{this.renderTodo()}
</div>
);
}
TodoForm.index.js:
class TodoForm extends React.Component { // eslint-disable-line react/prefer-stateless-function
constructor(props) {
super(props);
this._handleSubmit = this._handleSubmit.bind(this);
}
_handleSubmit(formData) {
console.log('');
console.log('OG: ', this.props.todo)
console.log('formData: ', formData);
const data = this.props.todo.update('title', formData.get('title'));
console.log('data: ', data);
console.log('');
// this.props.updateTodo(data);
}
render() {
const { handleSubmit, pristine, submitting } = this.props;
return (
<form className={`${styles.todoForm} card`} onSubmit={handleSubmit(this._handleSubmit)}>
<div className="card-block">
<label htmlFor="title">{this.props.todo.get('title')}</label>
<div className={'form-group'}>
<Field name={`title`} component="input" type="text" placeholder="Enter new title" className="form-control" />
</div>
</div>
<div className="card-block btn-group" role="group">
<button
className="btn btn-success"
type="submit"
disabled={pristine || submitting}
>
Submit
</button>
<button
className="btn btn-danger fa fa-times"
onClick={this.props.changeTodoEditMode}
>
</button>
</div>
</form>
);
}
}
const randomNum = (() => {
const thing = Math.floor(Math.random() * 1000) + 1;
console.log('thing: ', thing);
console.log('notThing: ', TodoForm.props);
return thing;
})();
export default reduxForm({
form: `todo-${randomNum}`,
})(TodoForm);
フォームに動的キーを与えるには、TodoFormでform属性を使用する必要があります成分:
renderTodo() {
if (this.state.editMode) {
return (
<TodoForm
form={'todo-' + this.props.todo.id}
todo={this.props.todo} changeTodoEditMode={this.changeTodoEditMode}
updateTodo={this.props.updateTodo}
/>
);
}
[...]
}
(の代わりにthis.props.todo.idをrandomNumにすることができます関数呼び出し)