Chisom Ozor
Chisom Ozor

Reputation: 11

Why is my useState value not updated when it is referenced from inside a function that runs on click

I have a state value for all the users in the project I am working on, and the state value is updated as I expect it to. The problem is when I try to reference the 'users' state from inside a function, I get the previous value of the state.

I thought it was just because useState updated asynchronously but I am getting the expected value when I reference the 'users' state from other parts of the app. I also tried putting the function inside a useEffect hook that runs every time the 'users' state runs but I still had no luck. The function in question runs with a click event.

const [users, setUsers] = useState([])

  useEffect(() => {
    const subscribe = onSnapshot( usersRef, snap => {
      let tempUsers = []
      snap.docs.forEach(doc => {
        tempUsers.push({ ...doc.data(), id: doc.id })
      })
      setUsers(tempUsers)
    })

    return () => {
      subscribe()
    }
  }, [] )

useEffect(() => { 
    const followBtn = document.querySelector('.follow-btn')
    console.log(users.find(person => person.id === 'uekUbQRcBRYiZpipQGhHUtjwNDA3'))
    console.log(users)
  
    const handleFollow = async () => {
      console.log(users.find(person => person.id === 'uekUbQRcBRYiZpipQGhHUtjwNDA3'))
      console.log(users)
    }

    followBtn.addEventListener('click', handleFollow)

    return () => {
      followBtn.removeEventListener('click', handleFollow)
    }
  }, [users])

the users array in the two above console logs are different, the one outside the function gives the expected value but the one inside the function gives the outdated value, and I am not altering it. The data is being pulled from firebase.

Upvotes: 0

Views: 353

Answers (1)

NoNam4
NoNam4

Reputation: 1795

You should move your click event logic to your button onClick event:

const [users, setUsers] = useState([])

useEffect(() => {
  const subscribe = onSnapshot( usersRef, snap => {

    setUsers(() => snap.docs.map(doc => {
      return { ...doc.data(), id: doc.id }
    }))
  })

  return () => subscribe()
}, [] )

useEffect(() => { 
  console.log('users changed', users)
  console.log(users.find(person => person.id === 'uekUbQRcBRYiZpipQGhHUtjwNDA3'))
}, [users])

const handleFollow = async () => {
  console.log('button click', users)
  console.log(users.find(person => person.id === 'uekUbQRcBRYiZpipQGhHUtjwNDA3'))
}

return (
  <button 
    onClick={handleFollow}
  >
    click me
  </button>
)

Upvotes: 0

Related Questions