3

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:

  1. existingTags starts with, say, ['hello']
  2. setSelectedTags is doing its thing.
  3. selectedTags is now ['hello', 'world', 'world'].
  4. Then I send tags to server, close modal, parent re-render.
  5. Now the tags returned by server is ['hello', 'world'], without the duplicates.
  6. Here's the thing: Now I open the modal again, I'm still seeing my values in 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?

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
kyw
  • 6,685
  • 8
  • 47
  • 59

1 Answers1

2

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.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • 1
    yea I have actually tried that. no dice. i guess my problem lies somewhere else. but im gonna accept this answer since it sounds definitive for the issue i laid out in general. thanks! – kyw Oct 26 '21 at 05:43
  • 1
    @kyw Sure thing. If you happen to post a new question regarding any deeper dive into the issue, feel free to ping me here with a link to it and I can take a look. – Drew Reese Oct 26 '21 at 05:48