I'm working on a form where some additional inputs will be shown based on the value of select. The value of select changes on selecting a different option, but the "numberOfUsers" text field does not become visible.
I can see the changed value being printed on the console. Yes is printed on selecting first option and No on selecting the select.
I don't understand why it doesn't work. Please let me know the mistakes I have done.
Below is the code I have written
import React from 'react'
import { useState } from 'react'
import { Grid } from '@mui/material'
import './Form.css'
export const AddStartupForm = () => {
const [fields, setFields] = useState({})
function handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
fields[name] = value
setFields(fields)
console.log(fields['revenueGenerated'])
}
return (
<Grid container sx={{py: 5}}>
<Grid item xs={1} sm={4}></Grid>
<Grid item xs={10} sm={4}>
<form>
<label htmlFor="startupName">Startup Name</label>
<input type="text"
name="startupName"
onChange={handleChange}
value={fields["startupName"]}
/>
<label htmlFor="countryName">Country</label>
<input type="text"
name="countryName"
onChange={handleChange}
value={fields["countryName"]}
/>
<label htmlFor="revenueGenerated">Do you make revenue?</label>
<select name="revenueGenerated"
onChange={handleChange}
value={fields["revenueGenerated"]}
>
<option disabled selected value=''> -- select an option -- </option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
{ fields['revenueGenerated'] === 'Yes' ?
<>
<label htmlFor="numberOfUsers">Sample Yes</label>
<input type="text"
name="numberOfUsers"
/>
</>
: null
}
</form>
</Grid>
</Grid>
)
}
CodePudding user response:
fields
is an object and updating a prop on that object does not change the reference to the object so react's equality check will not recognize a change (and therefore won't rerender).
Try changing
fields[name] = value
setFields(fields)
to
setFields({...fields, [name]: value})
CodePudding user response:
The state isn't updated, because the reference of the state doesn't change. You can try that by adding a console.log
before your return
statement:
console.log(fields);
return (...)
It never changes.
Try setting your fields like this:
function handleChange(event) {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
setFields({
...fields,
[name]: value
});
}
If you change your handler to use useCallback
, be sure to add the fields
as a dependency, so it get's changed:
const handleChange((event) => {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
setFields({
...fields,
[name]: value
});
}, [fields]);