Im using MUIs input field for a lot of input sections of my questionnaire and want to save it to my state variable that is an object which holds all my form values. How can I manipulate my formData object in a reusable MUI component?
Im currently passing formData as a prop to the component but am unsure how to use the setFormData inside the component since it will be a different property each time I use it.
I was thinking each question is a property of the state object formData so itll look like
formData{question1: 'foo', question2: 'bar'}
This is how the form looks at the moment (i dont mind changing the structure if it makes sense to do so
Take a look at InputField on the form (i also attached the component code)
<QuestionLabel>Do you have a "Nickname":</QuestionLabel>
<InputField value={props.formData.nickname}/>
<QuestionLabel>Preferred Language:</QuestionLabel>
<InputField value={props.formData.language}/>
<QuestionLabel>Occupation:</QuestionLabel>
<InputField value={props.formData.occupation}/>
This is how the component looks (im aware i will have to change this)
export default function InputField(props){
return(
<TextField
fullWidth
value={props.value}
variant='standard'
/>
)
}
Disclaimer First post so sorry if the format isn't perfect or if i attached the code snippets in a inconvenient way, please give me some pointers if thats the case
Since there is no two-way binding in react, the normal way of processing form input with controlled components is to pull the text from the specific dom element every time it changes. We do this using event.target.value to pull the data, but how do we then add it correctly to your state in a reusable component?
For that we would want to add a name tag to the input field, which we would then use when adding the value to our state. As you correctly stated, formData.someName = 'some text' We update our state in a changeHandler function that updates our state every time the input changes.
For example, assume we are passing setFormData, formData and a fieldName into the props:
export default function InputField(props){
const {setFormData, formData, fieldName} = props //destructure the props
const changeHandler = (event) => {
// updates the formData state of formData.name to equal event.target.value
setFormData({...formData, [event.target.name]: event.target.value})
}
return(
<TextField
fullWidth
name={fieldName}
value={formdata.fieldName}
onChange={changeHandler}
variant='standard'
/>
)
}
Using the above component would look something like this:
<InputField setFormData={setFormData} formData={formData} fieldName="question1">
I was able to get it working by passing the property into the component that needed to be changed; here is my handleChange function on the textfield component:
const handleChange = (event) => {
var formData = {...props.formData}
formData[props.property] = event.target.formData
props.onChange(formData)
}