Reputation: 7533
Pretty sure I'm missing something fundamental about React.
So here's the code:
export function EditTagsModal({existingTags}) {
console.log('existingTags', existingTags);
const [selectedTags, setSelectedTags] = React.useState(existingTags);
console.log('selectedTags:', selectedTags);
...
}
In a parent component, <EditTagsModal />
is consumed like this:
{tags && <EditTagsModal existingTags={tags} /> }
Here is how it goes down:
existingTags
starts with, say, ['hello']
setSelectedTags
is doing its thing.selectedTags
is now ['hello', 'world', 'world']
.tags
returned by server is ['hello', 'world']
, without the duplicates.selectedTags
(in that second console.log above) that has the duplicates, not the tags
(the first console.log) from my server.What's up with react?
Upvotes: 5
Views: 4935
Reputation: 202605
The selectedTags
state in the useState
hook is only initialized once.
If tags
remains a truthy defined array (even empty arrays are truthy and defined) then the EditTagsModal
component remains mounted by {tags && <EditTagsModal existingTags={tags} />}
. If the tags
value, and thus the existingTags
prop updates and EditTagsModal
is rerendered, then you should implement an useEffect
hook with a dependency on the existingTags
prop to update the local state when the prop value updates.
useEffect(() => {
setSelectedTags(existingTags);
}, [existingTags]);
useEffect
with a dependency array is synonymous to a class component's componentDidMount
and componentDidUpdate
lifecycle methods.
Upvotes: 5