Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[custom renderer] weird behavior of the useState hook #16171

Closed
krasimir opened this issue Jul 22, 2019 · 4 comments
Closed

[custom renderer] weird behavior of the useState hook #16171

krasimir opened this issue Jul 22, 2019 · 4 comments

Comments

@krasimir
Copy link

krasimir commented Jul 22, 2019

Do you want to request a feature or report a bug?

not a bug nor a feature (I probably missed something in my custom renderer host config)

What is the current behavior?

I have the following example:

function XXX() {
  const [ counter, setCounter ] = useState(0);
  console.log(counter);
  useEffect(() => {
    setCounter(42);
  }, [])

  return (
    <span style={ { cursor: 'pointer' } } onClick={ () => setCounter(counter + 1) }>
      XXX({ counter })
    </span>
  );
}
function App() {
  return (
    <XXX />
  );
}

Banana.render(<App />, document.querySelector('#root'));

All works fine until I click on the XXX(42) text. This is suppose to update the local state to 43 but it sets it to 1. And then no matter how many times I click it stays 1. I assume that it gets the initial value of 0 on ever render.

Here's the code of the example https://github.com/krasimir/react-custom-renderer-experiment/blob/master/src/index.js together with my custom host config. The same example works just fine using ReactDOM renderer. I tried to cover as many methods as possible and can't figure out why useState is not behaving correctly.

What is the expected behavior?

I expect to get the updated state value out of the useState call.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

"react": "16.8.6",
"react-reconciler": "0.20.4",
"scheduler": "0.13.6"

I'm testing under macOS, Chrome 75.

@graphicbeacon
Copy link

Looks like you need to retrieve the latest state value for counter:

setCounter(counter => counter + 1)

@krasimir
Copy link
Author

@graphicbeacon hm ... but why I have to do that. I mean this may fix the problem but I'll expect when calling setState to get my component re-rendered which will result into having a counter constant with the new value. That's how it works with react-dom renderer (here for example)

@eddiecooro
Copy link

I think you forgot to assign the new onClick callback to the dom node when the function's reference changes. So when you click on your span, the function created in the first render pass get's called. Therefore it doesn't matter what the value of the counter is, It's always 0 in the closure of the onClick function.

@krasimir
Copy link
Author

@Eddie-CooRo you nailed it. That was the reason. I had to basically amend my commitUpdate to re-assign the new handler. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants