web-dev-qa-db-ja.com

redux-forms v6を使用して、同じページに複数のフォームを作成するにはどうすればよいですか?

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だけです。ただし、各フォームキーは、すぐに呼び出される関数でランダムに生成されるはずです。

Todo Conundrums

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);
11
Kyle Truong

フォームに動的キーを与えるには、TodoFormform属性を使用する必要があります成分:

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.idrandomNumにすることができます関数呼び出し)

APIリファレンス: http://redux-form.com/6.0.2/docs/api/Props.md/

19
Misha K