Search code examples
reactjsreact-nativerelayjsgraphql-jsredux-framework

Integrating Relay with Redux in React Native App


I am new to react-native.My application currently uses redux,react-redux,router flux & navigator.

The back end i need to work with is GraphQL. What should i do now?

Can i integrate Relay to my app without affecting anything related to redux or should i dump redux and use relay?. What about lokka? Really confused!! Can someone help me with code examples or anything related to this issue?

Thanks in Advance :)


Solution

  • I use relay and redux in same application without much(I dont have any till today) issues(the App will be in production after few weeks). I could explain how I achieved it. (I am also new react-native and Js development, I don't claim this as the best approach, but at least it works for me as I intended)

    Setting up of relay and graphQL almost took a day of effort. For this use following commands:-

    npm install babel-core --save-dev
    npm install babel-preset-react-native --save-dev
    npm install babel-relay-plugin --save-dev
    npm install react-relay --save
    npm install graphql --save-dev
    npm install sync-request --save-dev
    

    then create a file named babelRelayPlugin.js and copy the below code.

    const getBabelRelayPlugin = require('babel-relay-plugin')
    const introspectionQuery = require('graphql/utilities').introspectionQuery
    const request = require('sync-request')
    
    const url = 'your_api_here'
    
    const response = request('POST', url, {
      qs: {
        query: introspectionQuery
      }
    })
    
    const schema = JSON.parse(response.body.toString('utf-8'))
    
    module.exports = { plugins: [getBabelRelayPlugin(schema.data, { abortOnError: true })] }
    

    and replace the code your .babelrc with this:-

    {
      "passPerPreset": true,
      "presets": [
        "./scripts/babelRelayPlugin",
        "react-native"
      ]
    }
    

    following classes may need to use this import statement:-

    import Relay, {
      Route,
      DefaultNetworkLayer
    } from 'react-relay'
    

    And my App.js file look like:-

      function configureStore(initialState){
          const enhancer = compose(applyMiddleware(
            thunkMiddleware,
            loggerMiddleware
            ),
            autoRehydrate()
          );
    
            return createStore(reducer,initialState,enhancer);
        }
    
        const store = configureStore({});
        persistStore(store, {storage: AsyncStorage})
        ////relay network layer injecting
        Relay.injectNetworkLayer(new DefaultNetworkLayer('your_api'))
        export default class App extends Component {
          render() {
            return (
              <Provider store={store}>
                {//here is your react-native-router-flux Navigation router}
                <NavigationRouter/>
              </Provider>
            );
          }
        }
    

    After injecting relay network layer, you could use the following code in any containers to call from relay. Here is an example render method of one of my containers:-

    render() {
        var value = 'some_value';
        return (
          <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
            <Relay.RootContainer
            Component={TestComponent}
            //relay_route is imported from relay_route.js
            route={new relay_route({id:value})}
            renderFetched={(data)=> {
              return (
                <TestComponent parentProps={this.props} {...data} />
              );}}
            />
          </View>
        ); 
    

    the relay_route.js should look something like

    class relay_route extends Route {
      static paramDefinitions = {
        userID: { required: true }
      }
      static queries = {
        user: () => Relay.QL`
          query { 
            user(id: $userID)
          }
        `
      }
      static routeName = 'UserRoute'
    }
    

    And My TestComponent looks like:-

    class TestComponent extends Component {
      render () {
        const user = this.props.user
        return (
          <Text>name: {user.name}</Text>
        )
      }
    }
    
    export default TestComponent = Relay.createContainer(TestComponent, {
      fragments: {
          user: () => Relay.QL`
          fragment on User {
            id,
            name
          }
        `
      }
    })
    

    For any doubts regarding relay, this documentation is classy to help us