AnApprentice AnApprentice -4 years ago 60
React JSX Question

How to dynamically build a redux form?

I'm looking to learn how to dynamically build a redux-form. Idea being, the component called, componentDidMount goes at fetches a list of items from the server and inserts them in the store, store.my_items:

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


Now that these items are in the store, I want to build the redux-form with a Field for each item in store.my_items.

Example, several of these dynamically created:

<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>


With react, redux-form, what would be the right way to approach building this type of dynamic redux form?

Thank you

Answer Source

I am following this approach for building a form dynamically. I am just declaring metadata of form fields (type, placeholder, the unique name of each field, etc.) like this:

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' },
        ],
      },
    ]

Now, I am just iterating over these fields and rendering input for each field like the way I have done in renderField component given below. My general form component looks like this:

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)

and passing fields to SimpleForm component like this:

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

Now it's your choice that you want to fetch fields like this from the server or just want to fetch only items and make fields like this (by passing item as the name of field) on the frontend.

By using this approach, I am able to re-use template based on given type.

If someone has a better approach to make a form dynamically, then I would love to learn that too.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download