Weird behavior using a generator function with React

Tags: , ,



Below is my stripped-down component. It has a generator function that is supposed to cycle through values.

const App = () => {
  const [state, setState] = useState("1")

  function* stateSwitch () {
    while (true){
      yield "2"
      yield "3"
      yield "1"
    }
  }

  const stateSwitcher = stateSwitch()

  const handleClick = event => {
    event.preventDefault()
    console.log(stateSwitcher.next().value)
    setState(stateSwitcher.next().value)
  }

  return (
    <div className="App">
      <button onClick = {handleClick}>{state}</button>
    </div>
  );
}

The behaviour of this is weird. Getting a new value displayed on the button takes one click, then two clicks, then one click again and so forth. The state is “3” sometimes, however, only “1” and “2” are ever logged.

I don’t understand how this happens and I suppose it has something to do with the React Component lifecycle that I don’t yet know. Can someone help me?

Answer

One or the other of console.log(stateSwitcher.next().value) and setState(stateSwitcher.next().value) is consuming one of the yields.

The generator is also redefined each render cycle.

Try instead

function* stateSwitch() {
  while (true) {
    yield "2";
    yield "3";
    yield "1";
  }
}

const stateSwitcher = stateSwitch();

export default function App() {
  const [state, setState] = useState("1");

  const handleClick = (event) => {
    event.preventDefault();
    const value = stateSwitcher.next().value;
    console.log(value);
    setState(value);
  };

  return (
    <div className="App">
      <button onClick={handleClick}>{state}</button>
    </div>
  );
}


Source: stackoverflow