如何动态构建redux表单?

IT技术 reactjs react-redux redux-form
2021-04-25 11:07:36

我正在寻找学习如何动态构建 redux-form 的方法。想法是,称为 componentDidMount 的组件从服务器获取项目列表并将它们插入商店 store.my_items:

{'item1', 'itemB', 'itemZZZ', etc...} 

现在这些项目都在商店里,我想为 store.my_items 中的每个项目构建一个带有字段的 redux-form。

例如,其中几个是动态创建的:

      <div>
        <label>ItemXXX</label>
        <div>
          <label>
            <Field name="ItemXXX" component="input" type="radio" value="1" />
            {' '}
            1
          </label>
          <label>
            <Field name="ItemXXX" component="input" type="radio" value="2" />
            {' '}
            2
          </label>
        </div>
      </div>

使用 react、redux-form,构建这种动态 redux 表单的正确方法是什么?

谢谢

2个回答

我正在遵循这种动态构建表单的方法。我只是像这样声明表单字段的元数据(类型、占位符、每个字段的唯一名称等)

const fields = [
      { name: 'name', type: 'text', placeholder: 'Enter Name' },
      { name: 'age', type: 'number', placeholder: 'Enter age' },
      { name: 'email', type: 'email', placeholder: 'Enter Email' },
      { name: 'employed', type: 'checkbox' },
      {
        name: 'favouriteColors',
        type: 'select',
        options: [
          { label: 'Red', value: 'red' },
          { label: 'Yellow', value: 'yellow' },
          { label: 'Green', value: 'green' },
        ],
      },
    ]

现在,我只是迭代这些字段并为每个字段渲染输入,就像我在下面给出的renderField组件中所做的那样。我的通用表单组件如下所示:

import React from 'react'
import { Field, reduxForm } from 'redux-form/immutable'

const renderField = ({ input, field }) => {
  const { type, placeholder } = field
  if (type === 'text' || type === 'email' || type === 'number' || type === 'checkbox') {
    return <input {...input} placeholder={placeholder} type={type} />
  } else if (type === 'select') {
    const { options } = field
    return (
      <select name={field.name} onChange={input.onChange}>
        {options.map((option, index) => {
          return <option key={index} value={option.value}>{option.label}</option>
        })}
      </select>
    )
  } else {
    return <div>Type not supported.</div>
  }
}

const SimpleForm = ({ handleSubmit, fields }) => {
  return (
    <div>
      {fields.map(field => (
        <div key={field.name}>
          <Field
            name={field.name}
            component={renderField}
            field={field}
            />
        </div>
      ))}
      <div onClick={handleSubmit}>Submit</div>
    </div>
  )
}

export default reduxForm({
  form: 'simpleForm'
})(SimpleForm)

并将字段传递给 SimpleForm 组件,如下所示:

<SimpleForm fields={fields} onSubmit={() =>{}}/>

现在,您可以选择从服务器获取这样的字段,或者只想获取项目并在前端创建这样的字段(通过将项目作为字段名称传递)。

通过使用这种方法,我可以根据给定的类型重用模板。

如果有人有更好的方法来动态制作表单,那么我也很想学习。

编辑:如果我们必须动态传递表单名称,则需要进行一些小的更改:

export default reduxForm({})(SimpleForm)

我们可以在这个组件中传递表单名称,如下所示:

<SimpleForm form={'simpleForm'} fields={fields} onSubmit={() =>{}} />

您可以创建一个组件表单并在.map()函数中使用它,然后将 formName 作为props传递给这样的...

render() {
 return(
   <div>
     {yourDataFromServer.map((item, index) => 
      <ReduxFormComp
        form={`${FORM_NAMES.SIMPLE_FORM}__${index}`}
        initialValues={item}
      />
    )}
   </div>
);
}

注意:当您使用 from initialValues 初始化表单时,所有字段名称都应与您的数据相同。