Reputation: 251
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
Upvotes: 1
Views: 118
Reputation: 4974
You can't push new item to the array for updating state. Your push
will mutate the state directly and that could potentially lead to error prone code. If you would like to push item to array of states, you can make a shallow copy of the state with destructuring-assignment
, push to it and finally update the state with the copied array :
const addAlias = () => {
const updatedFormValue = formValue;
let copy = [...updatedFormValue.aliases];
copy.push("");
setFormValue(updatedFormValue);
setFormAliases(copy);
}
Upvotes: 1
Reputation: 260
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,""])
Upvotes: 1