Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React State Variables Not Updating in Function

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

like image 583
Elliptica Avatar asked Dec 27 '25 16:12

Elliptica


1 Answers

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);
like image 135
Abdulmuhaymin Avatar answered Dec 31 '25 17:12

Abdulmuhaymin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!