3

I have a project that I am going to add tags, similar to this site. I want to first check if the tag has already been selected by the user. I have a for loop to see if the tag added equals the tags that are already there.

If I make a tag named Jack, it will work just fine. If I create another tag named Jack, now I have two Jacks(not good). On the third attempt, it doesn't add another Jack (good.)

Here is my relevant code. I have added the console as well. My useState setTagAlreadyThere on is being ignored until the third attempt, when it should go to true on the second attempt. What am I doing wrong here?

const [tagsFound, setTagsFound] = useState([]) const [tagsAdded, setTagsAdded] = useState([]) const [tagAlreadyThere, setTagAlreadyThere] = useState(false) const gatherTags = (tags) => { setTagAlreadyThere(false) console.log(tagAlreadyThere) if (tagsAdded.length === 0) { setTagsAdded([...tagsAdded, tags]); } else { console.log(tagsAdded) for (let i = 0; i < tagsAdded.length; i++) { console.log(tagsAdded[i]) if (tags === tagsAdded[i]) { console.log(tagsAdded[i]) console.log(tags) setTagAlreadyThere(true) console.log(tagAlreadyThere) } } console.log(tagAlreadyThere) if (tagAlreadyThere === false) { setTagsAdded([...tagsAdded, tags]); console.log(tagsAdded) } else { return } } setPostTag('') } 

Console.

TagAdder.tsx:9 jack postarticle.tsx:64 false postarticle.tsx:69 ["jack"] postarticle.tsx:72 jack postarticle.tsx:75 jack postarticle.tsx:76 jack postarticle.tsx:78 false postarticle.tsx:81 false postarticle.tsx:84 ["jack"] post.tsx:6 {} postarticle.tsx:92 (2) ["jack", "jack"] post.tsx:6 {} postarticle.tsx: 

92

2
  • Where is your hooks? Commented Aug 31, 2019 at 3:45
  • just useState. I'll post Commented Aug 31, 2019 at 3:50

2 Answers 2

2

no offense but you code has so many unnecessary stuff.

So why it is happening. Because you tagAlreadyThere is not updated yet. And you are checking it is value.

const gatherTags = (tags) => { if (!tagsAdded.inlcudes(tags)) { setTagsAdded([...tagsAdded, tags]); setPostTag('') } }

No need for const [tagAlreadyThere, setTagAlreadyThere] = useState(false)

Sign up to request clarification or add additional context in comments.

1 Comment

Offense? No sir, I totally agree with you. I'm still learning, about a year in, and am trying super hard to get my code tighter. I appreciate your AWESOME answer!
1

I will give you an idea on why this code causes a lot of issues, no offense.

First is you call a hook inside a loop synchronously, because React.useState hook is asynchronous just like this.setState in class-based and it batches updates to gain performance.

I have an example here on Code Sandbox: Calling Hooks Sync and Async

Second is if your new state is computed from the previous state, use the callback style because you can access the updated previous state, example:

setTagsAdded(prevTagsAdded => [...prevTagsAdded, tags]) 

You can check the documentation here: Functional Updates

Hope this helps!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.