0

I have component that have state as object

const [data, setData] = useState({
  input, 
  output: '', 
  enableCopyToClipboard: true,
}

When listen to Observable I do following:

  // reset state before loading stream
  setData({ 
    ...data, 
    output: '',
    enableCopyToClipboard: false,
  });

  loadingStream(request).subscribe((response) => {
    resText.push(response.text);
    setData({ 
      ...data, 
      output: resText.join(''), 
    });
  });

Problem is my enableCopyToClipboard variable in state stays true when it should be false while streaming is ongoing. No idea why.

2 Answers 2

1

You can use the callback function to set the new data. So you'll always have the most up to date version of the state. This prevents the override of the old version of the state.

// reset state before loading stream
setData((prevData) => ({
  ...data,
  output: "",
  enableCopyToClipboard: false,
}));

loadingStream(request).subscribe((response) => {
  resText.push(response.text);
  setData((prevData) => ({
    ...prevData,
    output: resText.join(""),
  }));
});

You could also set the enableCopyToClipboard to false by default on the subscribe.

loadingStream(request).subscribe((response) => {
  resText.push(response.text);
  setData((prevData) => ({
    ...prevData,
    enableCopyToClipboard: false,
    output: resText.join(""),
  }));
});
Sign up to request clarification or add additional context in comments.

Comments

0

Multiple state updates in the same render, as well as state updates within a closure, can cause this problem. An often recommended approach is to use the callback version of state updates. For example:

setData(d => ({ 
  ...d, 
  output: '',
  enableCopyToClipboard: false,
}});

loadingStream(request).subscribe((response) => {
  resText.push(response.text);
  setData(d => ({ 
    ...d, 
    output: resText.join(''), 
  }));
});

In the case of state updates within a closure, the difference here is that the data variable isn't being captured by that closure and there's no dependency on it. In the case of batched state updates, the difference here is that the callback uses the current state in the batch sequence rather than the state at the time of rendering.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.