diegohaz / constate

React Context + State

Home Page:https://codesandbox.io/s/github/diegohaz/constate/tree/master/examples/counter

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can I update app state (global) from onMount in another component?

ripern opened this issue · comments

The following code will just update the component MyView's state. I want to update app's state, but how? If I put an onMount on the app container (context="app") it will never be run since it's not the first being called as by design (and in your documentation).

const onMount = async ({ state, setState }) => {
  try {
    doSomething()
  } catch (error) {
     setState({ showSnackbar: true, snackbarMessage: error.msg })
  }
}

const ConnectedMyView = props => (
  <Container context="myview" onMount={({ state, setState }) => onMount({ state, setState })}>
    {() => (
      <Container context="app">
        {({ foo }) => (
          <MyView foo={foo} {...props}/>
        )}
      </Container>
    )}
  </Container>
)
commented

What do you want to update in app's state? Swapping containers doesn't work?

<Container context="app">
  {({ foo }) => 
    <Container context="myview" onMount={foo}>
      ...
    </Container>
  }
</Container>

Also, note that onMount will be executed only once per context. If you have different contexts (like app and myview), you can have different onMounts.

When using context, all Containers of the same context behave as a single unit, which means that onMount will be called only for the first mounted Container of each context.

I want to update a snackbar message and show it. The snackbar being declared in App. The thing about onMount not being executed more than once per context is what I tried to mention in first post. However, I solved it by declaring an effect in the app container. To pass it to the myview container I also had to swap the containers (obviously) like you suggested.

const appEffects = {
  showError: () => ({ setState }) => {
    setState({ showSnackbar: true, snackbarMessage: 'Could not update view' })
  },
}

const onMount = async ({ showError }) => {
  try {
    doSomething()
  } catch (error) {
    showWalletError()
  }
}

const ConnectedMyView = props => (
  <StateContainer context="app" effects={appEffects}>
    {({ showError }) => (
    <StateContainer context="myview" onMount={() => onMount({ showError })}>
      {(foo) => (
      <MyView foo={foo} {...props}/>
      )}
    </StateContainer>
  )}
  </StateContainer>
)

Thanks for your quick response!
Btw, do you think React Hooks will replace constate?

commented

Btw, do you think React Hooks will replace constate?

The current v1 alpha is built with Hooks in mind. I talked about it here: https://github.com/diegohaz/constate/blob/master/MIGRATING_FROM_V0_TO_V1.md#why-did-the-api-change