How to dynamically build a reduction form?

I want to learn how to dynamically build a reduction form. The idea, a component called componentDidMount, selects a list of items from the server and inserts them into the store, store.my_items:

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

Now that these items are in storage, I want to create a reduction form with a field for each item in store.my_items.

Example: several of them are 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 responsive, redux-form, what would be the right approach to building this type of dynamic reduction form?

thanks

+1
source share
2 answers

I follow this approach for dynamically building a form. I simply declare the metadata of the form fields (type, placeholder, unique name of each field, etc.) as follows:

 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 just iterate over these fields and prints the input for each field, as was done in the renderField component below. My common form component is as follows:

 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 pass the fields to the SimpleForm component as follows:

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

Now you choose whether you want to receive such fields from the server, or simply want to receive only the elements and create such fields (passing the element as the field name) in the interface.

Using this approach, I can reuse a template based on a given type.

If someone has a better approach to make the form dynamic, then I would also like to know about it.

+1
source

you can create a component form and use it in the .map() function and pass formName as properties like this ...

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

NOTE. When you use initialValues ​​to initialize your form, all field names must match your data.

+1
source

Source: https://habr.com/ru/post/1269401/


All Articles