I am creating a next application that pulls the form fields from a firestore collection. The form fields can be changed on the database and the changes reflect on the form. I render the text fields dynamically like below.
{
formfield && formfield
.filter((items => items.type === 'text'))
.sort((a,b) => (a.order_by > b.order_by) ? 1 : -1)
.map(item => {
return (
<div className="input-field mb-40" key={form_item.id}>
<input
placeholder={form_item.place_holder}
type="text"
id={ item.item_id }
required = {item.required}
onChange={e => setItem(e.target.value)}
/>
<label htmlFor="full_name" className="active fnt-16">
{ form_item.label }
</label>
</div>
)
})
}
The challenge I am facing is with handling the onChange. I would like to use the useState hook but don't know how to loop through it and update based on the field ID which is acquired from the database.
I have tried
textfields && textfields.map((text, index) => {
let textF = text.item_id;
let setTextF= 'set' + textF;
[text, setTextF ] = useState('')
})
But this doesn't work as it says I can't assign string to `setTextF`.
Does anyone know how to go about this?
I'm going on the assumption that you want to use useState to hold form data until you resubmit it. You've already got the code to build the form, so I think you want to hold an object containing all the k/v pairs. So at the top of your component:
const [text, setText] = useState({})
Then you can set the defaults from the server:
textfields && textfields.map((text, index) =>{
setText({...text, {index: text.item_id}}) // not really sure what you want here
})
Now you've built up an object that holds the state of your form. To change it:
onChange={e => setText({...text, {index: e.target.value}})}
I'm not really clear what your state object is supposed to look like based on what you have here, but this is the general pattern I think you're looking for. It's conventional to use the field names as keys so you get an object that's like {name: 'Joe', email: 'joe@joe.com'} or whatever.