如何在 React Native 中正确地将 Apollo 客户端连接到 Redux
Posted
技术标签:
【中文标题】如何在 React Native 中正确地将 Apollo 客户端连接到 Redux【英文标题】:How to properly hook up Apollo Client to Redux in React Native 【发布时间】:2018-04-02 21:00:00 【问题描述】:过去几个小时我一直在研究这个问题,现在我非常接近解决这个问题。现在似乎一切正常,但我的组件中没有 this.props.mutate
包裹它的 Apollo HOC。
我将 Apollo 连接为减速器,因此在我的组件中,我希望看到 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
中有 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
我删除了 Apollo reducer 和客户端引用。
./src/App.js
我将 Apollo Client 放在根组件中。我从 Nader Dabit 的 Medium 帖子中获得了这项技术。他在 GitHub 存储库中对此进行了说明:
https://github.com/react-native-training/apollo-graphql-mongodb-react-native https://medium.com/react-native-training/react-native-with-apollo-part-2-apollo-client-8b4ad4915cf5下面是它的实现方式:
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
【问题讨论】:
我认为options.props
是我需要的。我目前正在研究它。
对于将来看到此内容的任何人,请阅读有关 AsyncStorage 的 React Native 文档。您应该创建自己的实例。不要直接使用它,因为它具有全局元素。我的代码显示是这样的,但这是因为代码未完成。
【参考方案1】:
当您使用compose
时,您的 HOC 的顺序很重要。在您的代码中,您的第一个 HOC (connect
) 添加的道具可供其后的所有 HOC (withFormik
和 graphql
) 使用。 withFormik
添加的道具只对graphql
可用。 graphql
添加的 props 不适用于其他两个 HOC(仅组件本身)。
如果您将顺序重新排列为compose
-> graphql
-> withFormik
,那么您应该可以在withFormik
中访问props.mutate
。
此外,虽然您可以集成 Redux 和 Apollo,但这只是防止您拥有两个独立的商店。将现有存储传递给 Apollo 不会更改 graphql
HOC 的 API。这意味着,无论您使用什么商店,当您正确使用 HOC 时,您仍然会得到一个 data
道具(或用于突变的 mutate
道具)。
虽然将 Apollo 与 Redux 集成确实会将 Apollo 的 store 暴露给您的应用程序,但您仍然应该像往常一样使用 Apollo。 在大多数情况下,这意味着使用 graphql
HOC 并利用 data.props
和 @ 987654339@(或者如果你通过选项传入一个名称,那么你称之为这些道具的任何东西)。
如果您需要直接调用 Apollo 客户端,请改用 withApollo —— 这会公开一个 client
属性,然后您可以使用它。 connect
在您的代码中公开的 apollo
道具只是 Apollo 使用的商店——它不是实际的客户端,因此它不会有像 mutate
这样的方法可供使用。不过,在大多数情况下,没有理由选择 withApollo
而不是 graphql
。
【讨论】:
很好,谢谢。考虑到 compose 实际在做什么,这是完全合理的。谢谢你的帖子;这非常有帮助。 你是说我可以在我的根组件中以相同的方式传递客户端,但只需省略将其连接到 Redux 的步骤? (很确定我的网络应用程序就是这样做的)。 大声笑,我只是自欺欺人。在我提交表单之前,this.props
中实际上没有任何可见的内容。我从 Redux 中删除了 Apollo,所以现在它与我的 Web 应用程序完全匹配,我刚刚收到一个网络请求错误,因为我还没有创建用户,所以它肯定可以工作。再次,您的帖子非常有帮助,谢谢。我将更新我的帖子以说明已解决的代码(对于任何未来的搜索者)。以上是关于如何在 React Native 中正确地将 Apollo 客户端连接到 Redux的主要内容,如果未能解决你的问题,请参考以下文章
如何在 react-native for android 中更改应用程序图标背景颜色
需要的建议:如何正确地将 React 连接到 MongoDB