0

As title, in the code below, words is set based on flip state change. codepen link: https://codepen.io/jadecubes/pen/oNaMxaz?editors=1111

The original use is setWords(arrayGen[flip]); before return, but this way of writing causes infinite rendering (ref: React infinite rendering: a choice between mutating state array or not)

But in this case useEffect fails probably because the dependency is internal rather than of-side-effect. How to modify the code to avoid this issue?

// React.js libraries are added as external scripts in the JS settings of this pen

const { useState, useEffect } = React;

A = () => {
  const [info, setInfo] = useState("Hello world.");
  const [entered, setEntered] = useState("");

  return (
    <>
      <input
        type="text"
        onChange={(e) => {
          setInfo(e.target.value);
        }}
        onKeyUp={(e) => {
          if (e.key == "Enter") setEntered(info);
        }}
      />
      <B enteredTxt={entered} />
      <h1>{info}</h1>
    </>
  );
};

B = (props) => {
  const [words, setWords] = useState([]);
  const [flip, setFlip] = useState(true);
  if(props.enteredTxt.length==3) setFlip(!flip);

  useEffect(() => {//inifinite rendering
  setWords(arrayGen(flip));
}, [flip])
  //setWords(arrayGen[flip]);//infinite rendering
  return <div>{words}</div>;
};

const arrayGen = (flip) => {
  if(flip)
  return ["This ", "is ", "hello ", "world!"];
  else 
    return ["I ", "hate ", "the ", "world!"];
};
const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(<A />);
Yu Fang
  • 520
  • 5
  • 17
  • This explains. https://stackoverflow.com/questions/74034014/updating-state-to-the-same-state-directly-in-the-component-body/74036012#74036012 – Yu Fang May 14 '23 at 17:57

1 Answers1

0

I think the issue is with this snippet:

 if(props.enteredTxt.length==3) setFlip(!flip);

Which updates keep toggling the flip state on each render.

I think you may replace it inside useEffect like this:

UseEffect(()=> {
   If(props.enteredText.length === 3) setFlip(true)
},[props.enteredTxt])