I have a component which a prop value
which is an object, one of the properties of value
is aliases
which is an array of string. I have an add alias button which should add an alias to the object. I am displaying all aliases with .map
in the component, but when I add an alias the component does not re-render. I can see the state
updating properly with react dev-tools
in the browser, but the component does not re-render the updated list. What am I doing wrong?
import Accordion from "@components/common/Accordion"
import Alias from "./value-form/Alias"
const ValueItem = props => {
const { value } = props
/** EXAMPLE VALUE
"id": 1,
"name": "Primary Descriptor",
"programmaticName": "Primary_Descriptor",
"fileTypeDetailId": 9,
"fileType": "File Type no. 9",
"standardValue": "Outgoing",
"isActive": true,
"aliases": ["Alias 1", "Alias 2", "Alias 3"]
*/
const dispatch = useDispatch()
const [formValue, setFormValue] = useState(value)
const [formAliases, setFormAliases ] = useState(value.aliases)
const addAlias = () => {
const updatedFormValue = formValue;
updatedFormValue.aliases.push("");
setFormValue(updatedFormValue)
setFormAliases(updatedFormValue.aliases)
}
return (
<Accordion
key={value.id}
title={value.name} />
}
>
<div className={styles.valueFormContainer}>
{formAliases.map((alias) => {
return ({alias})
}
)}
<Button handleChange={() => { addAlias()}} buttonLabel="+ Add Alias" buttonTypes={["orange"]} />
</div>
</Accordion>)
}
export default ValueItem
Your problem is right here
const addAlias = () => {
const updatedFormValue = formValue;
updatedFormValue.aliases.push("");
setFormValue(updatedFormValue)
setFormAliases(updatedFormValue.aliases)
}
you are mutating the exists state.
https://reactjs.org/docs/hooks-state.html
in your case i'd use
setFormValue(prevState=>[...prevState,aliases:[...prevState.aliases,""])