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.

Global state returned by useGlobal() does not subscribe to changes.

See original GitHub issue
import { addReducer, setGlobal, useDispatch, useGlobal, getGlobal } from "reactn";

// Initialize the global state with the value 0.
setGlobal({ value: 0 });

// When the increment reducer is called, increment the global value by X.
addReducer("increment", (global, dispatch) => ({
  value: global.value + 1
}));

const Post = props => {
  const increment = useDispatch("increment");
  const [global] = useGlobal();

  return (
    <>
      <Button
        onClick={() => {
          increment();
          // increment(global.value); // it works
        }}
      >
        {global.value}
      </Button>
    </>
  );
};

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
CharlesStovercommented, Jan 25, 2020

I think this is due to the asynchronous nature of your lifecycle methods. Change useEffect to useLayoutEffect when you are synchronizing states. useLayoutEffect will fire after render but before paint, which is what you want in this case. In the above Stackblitz example, you are changing local state, repainting, then changing global state (useEffect). What you want is to change local state, change global state (useLayoutEffect), then repaint.

As to why one component renders correctly and the other doesn’t, I think that is just an implementation detail of React that should not be of concern. They both pass unit tests for re-rendering on state change. When dealing with proper lifecycle methods, this issue doesn’t arise. When dealing with improper lifecycle methods, the resulting behavior need not be accounted for.

Hope this helps. Great find! Without further reasoning, I believe this behavior is a side effect of the wrong lifecycle hook and that useLayoutEffect is the correct lifecycle hook for the intended behavior of the application.

0reactions
ASHFAQPATWARIcommented, Jan 22, 2020

@CharlesStover any update on this one?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Global state management in React with global variables and ...
Global states are used when components need to share states. React provides a very good and simple way to manage local state(React hooks) ......
Read more >
Not able to get state setter from context API, getting setGlobal ...
I have an issue with a React app. I need to keep an array of items in my global state. This is my...
Read more >
Manage global state with React hooks. | by Charles Stover
useGlobal supports both state and reducers with a single hook. useGlobal can return the entire global state by not providing a parameter.
Read more >
Global state with React | Basefactor
In other words, every component subscribed to our global state will re-render upon a context change, which in some scenarios might lead to...
Read more >
Creating a Global State with React Hooks - This Dot Labs
If that global state changes, it doesn't mean that the change is ... that contains special subscription links to a Redux global state....
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