-1

i'm trying to make a function that add a keyword if is not already in the array, if it is shows a error message, but the problem is that the includes() method doesn't work properly, it shows false first (when a word is not in the array), then true (because it is in the array) and then false again if i don't change the word.

I don't know why this is happening but it happens also with indexOf(). Maybe its a react problem with rendering or something like that.

Between if its another way to take an input value and do this, it is welcome

const [repeatedKeyWord, setRepeatedKeyWord] = useState(false)

let keyWords = []

const addKeyword = () => {
    let keyword = document.getElementById('keyword').value;
    const exist = keyWords.includes(keyword);
    console.log(exist)

    if (keyword && !exist){
        console.log('in')
        keyWords.push(keyword)
        setRepeatedKeyWord(false)   
    }

    setRepeatedKeyWord(exist? true : false)
    console.log(keyWords)
}
<PlusIcon className="w-6 text-firstColor cursor-pointer mr-2" onClick={addKeyword} />

enter image description here

Lucas
  • 27
  • 6

1 Answers1

2

You must store your keywords in useState, otherwise you lose the value between re-renders of your component. Thereafter, you can use .includes on your array. React ensures that you'll always have the latest value (e.g. 'snapshot' of your state).

Also note that when you are trying to compute a new state value (i.e. updating your array) you are dependent on the previous value of your state. If that is the case, you can pass a function to the setState function. Have a look at this issue where I have included a link to a working codesandbox for updating previous state values.

As a side note, I would suggest to avoid using let to declare your variables. Only use the let keyword if you are certain that you will re-assign a new value to your variable. Otherwise using const might be better to avoid mistakes.

const [keywords, setKeyWords] = useState([])

const addKeyword = () => {
  const keyword = document.getElementById('keyword').value;

  return setKeywords((prevState) => {
    if (prevState.includes(keyword)) {
       return [...prevState] 
   }
    return [...prevState, keyword]
  })
}
<PlusIcon className="w-6 text-firstColor cursor-pointer mr-2" onClick={addKeyword}
Apostolos
  • 10,033
  • 5
  • 24
  • 39
JnsBne
  • 121
  • 6
  • Thanks, do u have something to learn how react re renders works? cause sometimes i dont know how works and its confusing – Lucas Aug 22 '22 at 11:45
  • You're welcome! I also added another codesandbox example (https://codesandbox.io/s/thirsty-chihiro-y7w6o0?file=/src/App.tsx). I recently came across a good blog post about re-renders in React. You can check it out here: https://www.joshwcomeau.com/react/why-react-re-renders/ – JnsBne Aug 22 '22 at 11:50