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

Updating context only works in a single route? #241

Closed
SatyaFariz opened this issue May 16, 2019 · 11 comments · Fixed by #245
Closed

Updating context only works in a single route? #241

SatyaFariz opened this issue May 16, 2019 · 11 comments · Fixed by #245

Comments

@SatyaFariz
Copy link

I have a global context that I need to access from all routes. If I update the context value it only takes effect in the same route. It goes back to the default value after I navigate to a different screen.

@grahammendick
Copy link
Owner

Each screen is a separate React tree. The screens don’t show a common React root element. To share data between screens you’ll need a global store variable outside of the component tree. I’ve created a redux sample to show how this works.

@SatyaFariz
Copy link
Author

I am using Relay for global state management in my app. Do I need to install Redux which is another state management library for this functionality to work?

@grahammendick
Copy link
Owner

You don't need to install Redux, that was just an example. But you will need a global store outside of the component tree. How does the store context work in Relay?

@SatyaFariz
Copy link
Author

SatyaFariz commented May 16, 2019

I don't know exactly how the global store works internally in Relay. It uses some kind of environment to access the store. It flattens all the data in Relay Store with unique global id. But the data has to come from graphql query from graphql server.

@grahammendick
Copy link
Owner

I don't know Relay well enough to comment. Redux works because it fires an event to all subscribers whenever the store updates. Two separate React roots can listen to the same store and re-render in response to updates. Can you put a similar notification/subscription layer on top of Relay?

@SatyaFariz
Copy link
Author

SatyaFariz commented May 16, 2019

I don't think so because I store the environment in the context mentioned above. And I need to create a new environment (updating the context value) if I want to clear all the cache in the relay store (for example when the user logs in/out). I need to store the environment in react context because I will need it somewhere down in the react hierarchy for performing Relay Mutation.

@grahammendick
Copy link
Owner

Can you re-use the same environment across all screens? So different contexts but same environment?

@SatyaFariz
Copy link
Author

This is my code

import React, { Component } from 'react'
import RelayContext from './RelayContext'
import createRelay from './createRelay'

class RelayProvider extends Component {
  state = {
    environmentID: null,
    environment: createRelay(),
    resetEnvironment: (environmentID) => {
      if(!environmentID)
        throw new Error('Environment needs an ID')

      this.setState({ environment: createRelay(), environmentID })
    }
  }

  render() {
    return (
      <RelayContext.Provider value={this.state}>
        {this.props.children}
      </RelayContext.Provider>
    )
  }
}

export default RelayProvider

the environmentID here is just to make sure I have a different environment everytime I reset the environment. I got null environmentID after creating a new environment in a different screen.

@grahammendick
Copy link
Owner

What happens if you move createRelay outside of any component so you only create the environment once and then reuse it across screens?

var environment = createRelay();

class RelayProvider extends Component {
  state = {
    environment
  }

@SatyaFariz
Copy link
Author

SatyaFariz commented May 16, 2019

It should work but I'm still not really sure how relay handle the cache, let's say after the user logs in as a different user.
Also I need to reset the environment to trigger the rerender of QueryRenderer component provided by relay after the user logs in/out.

@grahammendick
Copy link
Owner

I've started work on bringing all scenes under a single React root element. This would help with Relay integration as well as other benefits

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

Successfully merging a pull request may close this issue.

2 participants