Be careful when handling React State in event handler

Use useRef hooks if you are registering a React State handling function as an event listener to an element or object and you can't update its value.

Event Listener

problem

React may have little use, but there are cases where you want to register a function that updates the State as an event listener for an element or object. Especially likely is the case of building an application that uses WebSocket such as video call, voice call, text chat.

// This example does not work
var socket = io.connect();
cont[(messages, setMessages)] = React.useState([]);

socket.on("data", function (data) {
  setMessages(messages.concat(data));
});

If a function that registers as an event listener handles State, it means that it is not updated occurs. The above case expects us to add a message when we receive the data, but In this case, only the most recent message is always kept.

This is a problem.

Cause

The reason for this is that the function registered in the event listener preserves the state of the function at the time of registration.

When a data event occurs, the State of the function in the event listener is always [] and and it will be an empty array. So adding data over and over again will result in only the most recent data being entered.

Solution

One way to solve this is to useref.

In the case of the above example, it can be modified as follows.

var socket = io.connect();
cont[(messages, _setMessages)] = React.useState([]);

const messagesRef = React.useRef(messages);
const setMessages = (data) => {
  messagesRef.current = data;
  _setMessages(data);
};

socket.on("data", function (data) {
  setMessages(messagesRef.current.concat(data));
});

Treating it as an instant constant gives us access to the current state. In addition, we update the state at the same time as updating the ref value to deal with the problem of it not being re-rendered because ref doesn't notify you when the value has been updated.

The following articles are more detailed examples of this problem.

Have a better React life! See you!

Updated at: Thu Jun 25 2020

© 2020-presentTerms|Privacy