title: How to properly hook up Apollo Client to Redux in React Native
body: <p>I've been researching this for the past couple hours, and I am now extremely close to solving this. Everything seems to be working now, but I do not have <code>this.props.mutate</code> in my component that has the Apollo HOC wrapping it.</p>
  
  <p>I wired Apollo up as a reducer, so in my component, I would expect to see <code>this.props.apollo.mutate</code> available, but it's not there.</p>
  
  <p>This is all that seems to be provided currently:</p>
  
  <blockquote>
    <p>console.log(this.props.apollo)</p>
  </blockquote>
  
  <pre><code>{"data":{},"optimistic":[],"reducerError":null}
  </code></pre>
  
  <p>Here is how it is hooked up:</p>
  
  <p><strong>./src/apolloClient.js</strong></p>
  
  <pre><code>import { AsyncStorage } from 'react-native'
  import { ApolloClient, createNetworkInterface } from 'react-apollo'
  
  const networkInterface = createNetworkInterface({
      uri: 'http://localhost:8000/graphql',
      opts: {
          credentials: 'same-origin',
          mode: 'cors'
      }
  })
  
  // networkInterface is half baked as I haven't got this far yet
  networkInterface.use([{
      async applyMiddleware(req, next) {
          if (!req.options.headers) req.options.headers = {}
          const token = await AsyncStorage.getItem('token')
          req.options.headers.authorization = token ? token : null
          next()
      }
  }])
  
  const client = new ApolloClient({
      networkInterface,
      dataIdFromObject: (o) =&gt; o.id
  })
  
  export default client
  </code></pre>
  
  <p><strong>./src/reducers.js</strong></p>
  
  <pre><code>import client from './apolloClient'
  
  export default combineReducers({
      apollo: client.reducer(),
      nav: navReducer,
      signup: signupReducer,
      auth: loginReducer,
  })
  </code></pre>
  
  <p><strong>./src/App.js</strong></p>
  
  <pre><code>import store from './store'
  import client from './apolloClient'
  
  const Root = () =&gt; {
      return (
          &lt;ApolloProvider store={store} client={client}&gt;
              &lt;RootNavigationStack /&gt;
          &lt;/ApolloProvider&gt;
      )
  }
  
  export default Root
  </code></pre>
  
  <p>Oh, and here's the bottom of my Login component (also fairly half-baked):</p>
  
  <pre><code>export default compose(
      connect(mapStateToProps, {
          initiateLogin,
          toggleRememberMe
      }),
      withFormik({
          validate,
          validateOnBlur: true,
          validateOnChange: true,
          handleSubmit: ({ tel, password }, { props }) =&gt; {
              props.apollo.mutate({
                      variables: { tel, password }
                  })
                  .then((res) =&gt; {
                      alert(JSON.stringify(res))
                      //const token = res.data.login_mutation.token
                      //this.props.signinUser(token)
                      //client.resetStore()
                  })
                  .catch((err) =&gt; {
                      alert(JSON.stringify(err))
                      //this.props.authError(err)
                  })
              //props.initiateLogin({ tel, password })
          }
      }),
      graphql(LOGIN_MUTATION, { options: { fetchPolicy: 'network-only' } })
  )(LoginForm)
  </code></pre>
  
  <p>It feels like I need an action creator and to manually map it to my component. What do I need to do to run this loosely shown mutation <code>LOGIN_MUTATION</code> onSubmit?</p>
  
  <p>I'm currently confused by the fact <code>this.props.apollo</code> has Apollo's data in it, but there is no <code>mutate</code>.</p>
  
  <p>I don't see the solution here: <a href="http://dev.apollodata.com/react/mutations.html" rel="nofollow noreferrer">http://dev.apollodata.com/react/mutations.html</a> or maybe I do -- is this what I need to be looking at?</p>
  
  <pre><code>const NewEntryWithData = graphql(submitRepository, {
    props: ({ mutate }) =&gt; ({
      submit: (repoFullName) =&gt; mutate({ variables: { repoFullName } }),
    }),
  })(NewEntry)
  </code></pre>
  
  <p>I'd like to get it to the point where the component can call the mutation when it needs to. I'd also like it to be available on <code>this.props.something</code> so I can call it from Formik's handleSubmit function, but I am open to suggestions that enable the best declarative scalability.</p>
  
  <p>[edit] Here is the code that I am considering solved:</p>
  
  <p><strong>./src/apolloClient.js</strong></p>
  
  <p>This file was scrapped.</p>
  
  <p><strong>./src/reducers.js</strong></p>
  
  <p>I removed the Apollo reducer and client reference.</p>
  
  <p><strong>./src/App.js</strong></p>
  
  <p>I put the Apollo Client inside the root component. I got this technique from Nader Dabit's Medium post. He illustrates this in a GitHub repo:</p>
  
  <ul>
  <li><a href="https://github.com/react-native-training/apollo-graphql-mongodb-react-native" rel="nofollow noreferrer">https://github.com/react-native-training/apollo-graphql-mongodb-react-native</a></li>
  <li><a href="https://medium.com/react-native-training/react-native-with-apollo-part-2-apollo-client-8b4ad4915cf5" rel="nofollow noreferrer">https://medium.com/react-native-training/react-native-with-apollo-part-2-apollo-client-8b4ad4915cf5</a></li>
  </ul>
  
  <p>Here is how it looks implemented:</p>
  
  <pre><code>const Root = () =&gt; {
      const networkInterface = createNetworkInterface({
          uri: 'http://localhost:8000/graphql',
          opts: {
              credentials: 'same-origin',
              mode: 'cors'
          }
      })
  
      networkInterface.use([{
          async applyMiddleware(req, next) {
              try {
                  if (!req.options.headers) req.options.headers = {}
                  const token = await AsyncStorage.getItem('token')
                  req.options.headers.authorization = token || null
                  next()
              } catch (error) {
                  next()
              }
          }
      }])
  
      const client = new ApolloClient({
          networkInterface,
          dataIdFromObject: (o) =&gt; o.id
      })
  
      return (
          &lt;ApolloProvider store={store} client={client}&gt;
              &lt;RootNavigationStack /&gt;
          &lt;/ApolloProvider&gt;
      )
  }
  
  export default Root
  </code></pre>