Home > front end >  How to use a dynamic variable in useEffect which works once when the page is loaded?
How to use a dynamic variable in useEffect which works once when the page is loaded?

Time:09-30

I am using socket.io on reactjs. There aren't any problems. Everything is working as expected.

I use it like this:

const [username,setUsername]=useState<string>('')
useEffect(() => {
        server.on("CORRECT_USERNAME_TO_LOGIN",(socketId: string) => {
          dispatch(authActions.setUsername(username))
          navigate(ROUTER_PATHS.activeUsers)
        })
}, [])

If the server emit to CORRECT_USERNAME_TO_LOGIN channel, this code structure works well. Bu there is a status. username variable is a dynamic value I have to use it when the server emit to the channel. But the username variable isn't current value it is initial value when the server emit. Is this because I use it in useEffect ?

CodePudding user response:

The problem is the scope of the CORRECT_USERNAME_TO_LOGIN listener function. You can fix this by used useRef, which will be outside the React's state. Example: I am assuming you are getting the username through an API call.

// declare userNameRef
const userNameRef = useRef();

...
// this is a callback function from an API
(data) => {
   // we are assuming that data has the username
   userNameRef.current = data;
}

...
// inside the useEffect use it like the following

useEffect(() => {
        server.on("CORRECT_USERNAME_TO_LOGIN",(socketId: string) => {
          dispatch(authActions.setUsername(userNameRef.current))
          navigate(ROUTER_PATHS.activeUsers)
        })
}, [])

CodePudding user response:

Get a reference to your state variable so you can always access it's current value using the reference:

import { useState, useEffect, useRef } from 'react'

// ...

const [username, setUsername] = useState<string>('')
const usernameRef = useRef(username)

// ...

useEffect(() => {
    server.on("CORRECT_USERNAME_TO_LOGIN",(socketId: string) => {
      dispatch(authActions.setUsername(usernameRef.current))
      navigate(ROUTER_PATHS.activeUsers)
    })
}, [])

You can update usernameRef like:

usernameRef.current = 'new-username'

wherever you're currently updating

  • Related