Home > Blockchain >  React State Variables Not Updating in Function
React State Variables Not Updating in Function

Time:03-12

I'm creating a chat app that works completely fine except for one issue: when I call a function that was passed to a child component, it uses the state variable's initial value, rather than its current value. I've included the code below and a snippit of the log that shows it using the wrong value. Why is it doing this? Is it related to LioWebRTC? Please advise.

Note: I added an extra button that calls the same function and the current state does print for that, so it seems like it's something to do with LioWebRTC? How is that even possible for it not to use the current state?

import React, { useState, useEffect } from 'react';
import { LioWebRTC } from 'react-liowebrtc';
import ChatBox from './ChatBox';


const ChatWrapper = props => {

  const [counter, setCounter] = useState(0)

  console.log("Correct Counter:", counter)

  useEffect( () => {
    setCounter(counter => counter  1 );
  } , [] );

  const addChat = (name, message, alert = false) => {};

  const join = (webrtc) => webrtc.joinRoom(props.roomID.toString());

  const handleCreatedPeer = (webrtc, peer) => {
    setCounter(counter => counter  1 );
  }

  const handlePeerData = (webrtc, type, payload, peer) => {
    console.log("Problem Counter: " , counter);
  }

  return (

    <div className='screenInterior'>

      <LioWebRTC
        options={{ debug: true,
                   dataOnly: true,
                   nick: "Blah" }}
        onReady={join}
        onCreatedPeer={handleCreatedPeer}
        onReceivedPeerData={handlePeerData}  >

        <ChatBox
          chatLog={null}
          onSend={(msg) => msg && addChat('Me', msg)}
        />

        <button onClick={handlePeerData}>Test</button>

      </LioWebRTC>

    </div>
  );
}

export default ChatWrapper;

enter image description here

CodePudding user response:

Create a reference of the state and pass it in the callback.

const [counter, setCounter] = useState(0)
const stateRef = useRef();
stateRef.current = counter;

const handlePeerData = (webrtc, type, payload, peer) => {
  console.log("Counter: " , stateRef.current);
}

Don't forget to import { useRef } from react.

For more information React hooks: accessing up-to-date state from within a callback

Edit: If you want to use a custom package, there is react-useStateRef help you have a state with reference in less code.

Import

import useState from 'react-usestateref'

Using

const [counter, setCounter, counterRef] = useState(0);
  • Related