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

Can't get updated state #12

Closed
otaviobonder-deel opened this issue May 1, 2019 · 6 comments
Closed

Can't get updated state #12

otaviobonder-deel opened this issue May 1, 2019 · 6 comments

Comments

@otaviobonder-deel
Copy link

I followed some examples and tried to implement the global state. On any first page load, I want to call my back end and get some data. So in my App.js file I used useEffect to call a function to update the state:

const App = () => {
  useEffect(() => {
    updateRates();
  }, []);

  return (
    <Fragment>
      <GlobalStateProvider>
        <GlobalStyle />
        <Routes />
      </GlobalStateProvider>
    </Fragment>
  );
};
export default App;

I debugged and I know that everything works right and the state is updated. However, on the page load, instead of accessing the updated state, I get my initial state.

Here is my Container that should receive the updated state, however receives the initial state:

function Main() {
  const [value] = useGlobalState("rates");

  return (
    <Container>
      <div>
        <h1>Save and transfer money home with 0% fee</h1>
        <p>VES: {value}</p>
      </div>
    </Container>
  );
}

export default withRouter(Main);

What can be wrong?

Thanks!

@dai-shi
Copy link
Owner

dai-shi commented May 1, 2019

It is because updatesRates is called before GlobalStateProvider is initialized.
Can you move useEffect in components under GlobalStateProvider?

I'm not sure how we can resolve this in general. Basically the use of setGlobalState is not recommended in this case and I'd use const setRates = useGlobalState('rates')[1].


(edit) There was my misunderstanding at first. There is no issue with initialization. The use of setGlobalState is fine and is better for performance in certain cases. You could even call it outside of GlobalStateProvider, but I wouldn't recommend it.

@otaviobonder-deel
Copy link
Author

otaviobonder-deel commented May 2, 2019

I tried moving it to the Routes component. It runs fine, however the same problem happens.

I didn't understand what you meant with const setRates = useGlobalState('rates')[1]

I tried to follow the fetch and onmount examples, but it didn't work

@dai-shi
Copy link
Owner

dai-shi commented May 2, 2019

I tried moving it to the Routes component. It runs fine, however the same problem happens.

Sorry. There might be something I misunderstand.
Could you provide a codesandbox to reproduce the problem please?

https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/05_onmount
This example without modification is working for you, correct?

@otaviobonder-deel
Copy link
Author

Could you provide a codesandbox to reproduce the problem please?

Yes: https://codesandbox.io/s/82kyyqw98j I just hard coded the setRates, because I won't integrate my API in codesandbox. But it replicates the issue.

This example without modification is working for you, correct?

I didn't try it, however I based my implementation using this one.

@dai-shi
Copy link
Owner

dai-shi commented May 3, 2019

@otaviobps Thanks for the code.

It's nothing to do with initialization which I mentioned in the first comment.

It's simply the usage of setGlobalState. The correct one is the following:

export const setRates = obj => {
  setGlobalState('loading', false);
  setGlobalState('rates', obj);
};

I didn't understand what you meant with const setRates = useGlobalState('rates')[1]

This is what I mean.

const Routes = () => {
  const setRates = useGlobalState('rates')[1];
  const setLoading = useGlobalState('loading')[1];
  useEffect(() => {
    setRates(2);
    setLoading(false);
  }, []);

  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/" component={Main} />
        <Route path="*" component={() => <h1>Page not found</h1>} />
      </Switch>
    </BrowserRouter>
  );
};

But, this will trigger re-render if rates or loading in state is changed.
So, setGlobalState would be better for performance. (My recommendation in the first comment is wrong.)

@dai-shi
Copy link
Owner

dai-shi commented Jun 9, 2019

Closing this for inactivity. Feel free to reopen it.

@dai-shi dai-shi closed this as completed Jun 9, 2019
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

2 participants