2017-10-22 175 views
1

我一直在研究這個過去幾個小時,現在我已經非常接近解決這個問題了。一切似乎現在正在工作,但我沒有this.props.mutate在我的組件中有Apollo HOC環繞它。如何在React Native中正確連接Apollo客戶端到Redux

我連接的Apollo作爲reducer,所以在我的組件中,我期望看到this.props.apollo.mutate可用,但它不存在。

這一切,這似乎是目前提供:

的console.log(this.props.apollo)

{"data":{},"optimistic":[],"reducerError":null} 

下面是它是如何迷上了:

./src/apolloClient.js

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) => o.id 
}) 

export default client 

./src/reducers.js

import client from './apolloClient' 

export default combineReducers({ 
    apollo: client.reducer(), 
    nav: navReducer, 
    signup: signupReducer, 
    auth: loginReducer, 
}) 

./src/App.js

import store from './store' 
import client from './apolloClient' 

const Root =() => { 
    return (
     <ApolloProvider store={store} client={client}> 
      <RootNavigationStack /> 
     </ApolloProvider> 
    ) 
} 

export default Root 

哦,這是我的登錄組件的底部(也還算一半 - 烤):

export default compose(
    connect(mapStateToProps, { 
     initiateLogin, 
     toggleRememberMe 
    }), 
    withFormik({ 
     validate, 
     validateOnBlur: true, 
     validateOnChange: true, 
     handleSubmit: ({ tel, password }, { props }) => { 
      props.apollo.mutate({ 
        variables: { tel, password } 
       }) 
       .then((res) => { 
        alert(JSON.stringify(res)) 
        //const token = res.data.login_mutation.token 
        //this.props.signinUser(token) 
        //client.resetStore() 
       }) 
       .catch((err) => { 
        alert(JSON.stringify(err)) 
        //this.props.authError(err) 
       }) 
      //props.initiateLogin({ tel, password }) 
     } 
    }), 
    graphql(LOGIN_MUTATION, { options: { fetchPolicy: 'network-only' } }) 
)(LoginForm) 

這感覺就像我需要一個行爲離子創建器並手動將其映射到我的組件。我需要做什麼來運行這個鬆散顯示的突變LOGIN_MUTATION onSubmit?

我目前困惑的事實this.props.apollo有阿波羅的數據,但沒有mutate

我在這裏看不到解決方案:http://dev.apollodata.com/react/mutations.html或者我可以 - 這是我需要看的嗎?

const NewEntryWithData = graphql(submitRepository, { 
    props: ({ mutate }) => ({ 
    submit: (repoFullName) => mutate({ variables: { repoFullName } }), 
    }), 
})(NewEntry) 

我想讓它達到組件可以在需要時調用突變的點。我也希望它在this.props.something上可用,所以我可以從Formik的handleSubmit函數中調用它,但我願意提供可以實現最佳聲明性可伸縮性的建議。

[編輯]這裏是我正在考慮解決代碼:

./src/apolloClient.js

此文件被廢棄。

./src/reducers.js

我除去阿波羅減速器和客戶參考。

./src/App。js

我把阿波羅客戶端放入根組件。我從Nader Dabit的中文文章中獲得了這項技術。他說明了這一點在GitHub庫:

下面是它看起來如何實現的:

const Root =() => { 
    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) => o.id 
    }) 

    return (
     <ApolloProvider store={store} client={client}> 
      <RootNavigationStack /> 
     </ApolloProvider> 
    ) 
} 

export default Root 
+0

我覺得這個'options.props'就是我需要的。我正在研究它。 – agm1984

+0

對於將來看到此內容的任何人,請閱讀關於AsyncStorage的React Native文檔。你應該創建你自己的實例。不要直接使用它,因爲它包含全局元素。我的代碼顯示它是這樣的,但這是因爲代碼沒有完成。 – agm1984

回答

4

當您使用compose,你的肝卵圓細胞事項的順序。在你的代碼中,你的第一個HOC(connect)添加的道具可用於它之後的所有HOC(withFormikgraphql)。 withFormik添加的道具僅適用於graphql。其他兩個HOC(只是組件本身)都可以使用graphql添加的道具。

如果重新排列順序是compose - >graphql - >withFormik,那麼你應該有機會獲得props.mutatewithFormik

此外,雖然你可以集成Redux和Apollo,所有這一切阻止你有兩個獨立的商店。將現有商店傳遞給Apollo不會更改graphql HOC的API。這意味着,無論您使用的是什麼商店,當您正確使用HOC時,您仍然會獲得支持(或突變支持的mutate支持)。

雖然將Apollo與Redux集成在一起會將Apollo的商店暴露給您的應用程序,但您仍然應該像平常一樣使用Apollo。在大多數情況下,這意味着使用graphql HOC並使用data.propsdata.mutate(或者如果您通過選項傳遞名稱,則稱爲這些道具)。

如果您需要直接致電Apollo客戶端,請改爲使用withApollo - 這會暴露您可以使用的client支柱。 connect在您的代碼中公開的apollo支柱只是Apollo使用的商店 - 它不是實際的客戶端,因此它不會有像mutate這樣的方法可用。但在大多數情況下,沒有理由通過withApollo而不是graphql

+0

很好,謝謝。鑑於組成部分實際在做什麼,這是非常有意義的。感謝您的帖子;這是非常有幫助的。 – agm1984

+0

你是說我可以在我的根組件中以相同的方式傳遞客戶端,但只是省略將它連接到Redux的步驟? (很確定這就是我的網絡應用程序正在這樣做)。 – agm1984

+1

大聲笑,我只是努力地拖着自己。在我提交表單之前,'this.props'實際上沒有任何可見的東西。我從Redux中刪除了Apollo,所以現在它完全匹配我的Web應用程序,並且我剛剛收到了網絡請求錯誤,因爲我還沒有創建用戶,所以它確實正常工作。再次,您的文章是非常有益的,謝謝。我會更新我的帖子來說明解決的代碼(對於任何未來的搜索者)。 – agm1984

相關問題