Javascript 如何使用redux forms v6在同一页面上创建多个表单?

Javascript 如何使用redux forms v6在同一页面上创建多个表单?,javascript,forms,reactjs,redux,redux-form,Javascript,Forms,Reactjs,Redux,Redux Form,我有一个简单的todo应用程序,其中我的redux商店包含一个“todo”数组。我的“Todo”组件映射到存储中的每个“Todo”,并呈现使用redux forms v6的“TodoForm”组件 现在,每个“todo”共享相同的表单名称/键,因此每次我在“标题”字段中输入内容时,它都会更改每个todo的“标题”。我找到了一个解决办法,就是使用唯一的字段名,但我担心随着应用程序的发展,这会使事情变得过于复杂,我更喜欢使用唯一的表单名,这样每个字段都可以有相同的名称,而不会干扰其他表单 (Todo

我有一个简单的todo应用程序,其中我的redux商店包含一个“todo”数组。我的“Todo”组件映射到存储中的每个“Todo”,并呈现使用redux forms v6的“TodoForm”组件

现在,每个“todo”共享相同的表单名称/键,因此每次我在“标题”字段中输入内容时,它都会更改每个todo的“标题”。我找到了一个解决办法,就是使用唯一的字段名,但我担心随着应用程序的发展,这会使事情变得过于复杂,我更喜欢使用唯一的表单名,这样每个字段都可以有相同的名称,而不会干扰其他表单

(TodoForm1、TodoForm2、TodoForm3都可以具有唯一的“标题”字段,而不是包含“标题1”、“标题2”、“标题3”字段的TodoForm)

我尝试访问TodoForm的道具,以便将每个表单的键设置为组件的唯一id,但组件似乎没有那么早就收到道具

我还尝试创建一个立即调用的函数,其中它会输出一个随机数,并使用该数作为表单的名称,但这也不起作用

如何映射所有TODO并使用唯一的表单键呈现v6 redux表单

下面是应用程序、控制台和redux开发工具的图片。有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>
    );
  }
renderToOS(todo){
如果(!todo){
不返回待办事项;
}
返回(
);
}
render(){
如果(!this.props.todos){
不返回待办事项;
}
返回(
嘿,我是主要部分
{this.props.todos.get('todos').map(this.rendertos)}
);
}
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>
    );
  }
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);
renderTodo(){
if(this.state.editMode){
返回(
);
}
返回(
{this.props.todo.get('author')}

{this.props.todo.get('title')}

); } render(){ 返回( {this.renderTodo()} ); }
TodoForm.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>
    );
  }
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);
class TodoForm扩展了React.Component{//eslint禁用line React/prefere无状态函数
建造师(道具){
超级(道具);
this.\u handleSubmit=this.\u handleSubmit.bind(this);
}
_handleSubmit(formData){
控制台日志(“”);
console.log('OG:',this.props.todo)
log('formData:',formData);
const data=this.props.todo.update('title',formData.get('title');
console.log('数据:',数据);
控制台日志(“”);
//this.props.updateTodo(数据);
}
render(){
const{handleSubmit,pristine,submiting}=this.props;
返回(
{this.props.todo.get('title')}
提交
);
}
}
常量randomNum=(()=>{
const thing=Math.floor(Math.random()*1000)+1;
log('thing:',thing);
log('notThing:',TodoForm.props);
归还物;
})();
导出默认reduxForm({
形式:`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}
        />
      );
    }
 [...]
}
renderTodo(){
if(this.state.editMode){
返回(
);
}
[...]
}
(可以使用randomNum函数调用代替this.props.todo.id)

API参考: