I am using the react-hook-form library to create a multi-step dynamic large form (over 70 fields). Most of my form fields are dynamic (user can add/delete more fields by clicking + button). In order to achieve this, I use react-hooks and add a hook for each dynamic field. But I feel like my code is not abstract enough and there might be a smarter way to do this. Below there is an example screenshot of my form:
Respective code for the hooks and form fields are here:
// hooks
const [sizes, setSizes] = React.useState([0]);
const [formats, setFormats] = React.useState([0]);
const [counter, setCounter] = React.useState(1);
// buttons
const addSizesFieldset = () => {
setSizes(prevIndexes => [...prevIndexes, counter]);
setCounter(prevCounter => prevCounter + 1);
};
const removeSizesFieldset = index => () => {
setSizes(prevIndexes => [
...prevIndexes.filter(item => item !== index)
]);
setCounter(prevCounter => prevCounter - 1);
};
const addFormatsFieldset = () => {
setFormats(prevIndexes => [...prevIndexes, counter]);
setCounter(prevCounter => prevCounter + 1);
};
const removeFormatsFieldset = index => () => {
setFormats(prevIndexes => [
...prevIndexes.filter(item => item !== index)
]);
setCounter(prevCounter => prevCounter - 1);
};
// form field arrays
{sizes.map(index => {
const fieldName = `sizes[${index}]`;
return (
<fieldset name={fieldName} key={fieldName} >
<h4>Sizes:</h4>
<label>
Size:
<input
type="text"
placeholder="Input"
name={`${fieldName}.size`}
ref={register}
/>
</label>
<button type="button" onClick={addSizesFieldset}>
+
</button>
<button type="button" onClick={removeSizesFieldset(index)}>
-
</button>
</fieldset>
);
})}
{formats.map(index => {
const fieldName = `formats[${index}]`;
return (
<fieldset name={fieldName} key={fieldName} >
<h4>Formats:</h4>
<label>
Format:
<input
type="text"
placeholder="Input"
name={`${fieldName}.format`}
ref={register}
/>
</label>
<button type="button" onClick={addFormatsFieldset}>
+
</button>
<button type="button" onClick={removeFormatsFieldset(index)}>
-
</button>
</fieldset>
);
})} ´´
Imagine you are doing these hook instants and const add/remove...Fieldset functions for seventy fields. It seemed too much duplication to me but I couldn't find any solution or a new idea other than "React can handle multiple hooks so no worries" comments.
If you want to try your ideas on codesandbox, I prepared below code as well:
