question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

State variable not updating in useEffect callback?

See original GitHub issue

Do you want to request a feature or report a bug? Bug, maybe? Although thinking about it more makes me think I’ve misunderstood something.

What is the current behavior? scroll state variable updates in rendered output but not inside handleScroll event callback.

I reckon this might be due to the fact that when handleScroll is defined scroll is 0, but scroll is defined in the scope above and should be updated when the component is re-rendered.

import React, { useState, useEffect } from "react";

const Scroller = () => {
  const [scroll, setScroll] = useState(window.scrollY);

  const handleScroll = () => {
    console.log(scroll); // scroll is always 0
    setScroll(window.scrollY);
  };

  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []); // runs once

  return <div id="scroll">{scroll}</div>; // scroll is correct
};

export default Scroller;

Please have a play: Edit yv8vwo44px

What is the expected behavior? scroll to be updated inside handleScroll event callback and in render output.

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

chrome        70.0.3538.77
react         16.7.0-alpha.0 - next
react-dom     16.7.0-alpha.0 - next

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:57
  • Comments:27 (3 by maintainers)

github_iconTop GitHub Comments

68reactions
AyWacommented, Nov 2, 2018

@evolutionxbox

It is not a bug, but the normal behavior from the doc. You can check this issue for more detail https://github.com/facebook/react/issues/14042

In short, if you are using the second parameter [] then you need to put all the variable (state or not) that you rely on.

So in your case, if you want to have access to the scroll state variable then you need to put [scroll] 😃

Obviously you maybe don’t want to do that, because you don’t want to create / remove event listener everytimes.

So the other way is to use an other effect, that will be responsible to modifying or getting the value. useReducer is one way. (see the other issue for code example)

I hope it is clear 😃

58reactions
gaearoncommented, Nov 2, 2018

Yep that’s right. We might offer a more convenient way in the future.

The rule of thumb is that if you use a variable in useEffect, you must declare it in the useEffect dependency array (or omit the array entirely). So in your example handleScroll should be in the array.

It’s true that this would cause it to re-subscribe more often. There is a way to avoid it but it’s not very convenient and might cause other issues in the future. We plan to add a better way later but it will take some time to implement.

Read more comments on GitHub >

github_iconTop Results From Across the Web

variable in useState not updating in useEffect callback
There are a couple of issues: You're not returning a function from useEffect to clear the interval; Your inc value is out of...
Read more >
[Resolved] useState not showing updated value - Freaky Jolly
When trying to get the updated state from the child to parent component, it is not updating the latest value in the console...
Read more >
Why React setState/useState does not update immediately
The answer: They're just queues ... React this.setState , and useState does not make changes directly to the state object. React this.setState ,...
Read more >
variable in useState not updating in useEffect callback-Reactjs
The issue here is that the callback from clearInterval is defined every time useEffect runs, which is when count updates. The value inc...
Read more >
Steps to Solve Changes Not Reflecting When useState Set ...
When the “useState” set method is not reflecting a change immediately, it may be due to the current closure of the state variable....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found