我在这里有一个无状态反应函数,我很乐意用减速器调用我的突变。注意,调用React.Component类中的变异是通过在组件内部添加一个函数来实现的,我不想这样,我想使用我的reducer来做到这一点。
使用最少的代码示例,我将显示我的设置
// index.js render function
[...] // imported variables
<ApolloProvider client={client}>
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<App />
</div>
</ConnectedRouter>
</Provider>
</ApolloProvider>
// Mutation
const Foo = gql`
mutation Foo($id: String) {
AddBar(id: $id) {
id
}
}
`;
// Component
[...] // other imports for below variables
const Comp = (props) => (
<div>
<button onClick={() => props.addFoo(props)}>Click</button>
</div>
)
const mapDispatchToProps = dispatch => bindActionCreators({
addFoo
}, dispatch)
export default connect(
mapDispatchToProps
)(graphql(Foo)(Comp))
// Reducer (very slimmed with just the action)
export const addFoo = (props) => {
// props contained the mutate function
props.mutate({
variables: {id: "1" }
})
// dispatch goes here but not needed.
}
好的,我尽可能地减少了这个例子。我的问题是我的变量没有传递给我的变异函数。如果我用一个硬编码id
并单击按钮,graphql会更改我的数据(是),但唯一的问题是变量没有通过。在检查器中,我确实看到了具有正确值的变量,但是......没有传递给mutate函数。
答案 0 :(得分:1)
一些想法......
首先,reducers不应该改变数据或进行异步调用。它们是纯粹的功能而没有副作用。
暂时将GraphQL从图片中删除并假设您只有一个REST调用,您通常会在Action Creator或类似内容中进行变异。 Redux中的Action Creators本质上是同步的,因此您可以使用Redux Thunks或Redux Sagas(或类似的东西)来帮助解决这个问题。
好的,让我们重新插入GraphQL。正如您所指出的,如果在组件中包含变异,则很难将其连接到Redux实现中。这两者是相互排斥的。在你的Redux实现中,你通常会进行异步fetch
调用,你可以使用没有React的Apollo客户端来mutate ......
const apolloClient = createApolloClient();
apolloClient.mutate({mutation: Foo}).then(handleResult)
现在,createApolloClient()
做了什么?您不希望每次都创建一个新的。该客户端维护缓存并可以处理重新使用客户端所带来的所有增值。这适用于React代码。您希望从React绑定执行任何查询以使用您在Redux操作创建器中使用的相同客户端。 createApolloClient()
函数需要创建一个客户端单例并将其返回,以便您在ApolloProvider
中使用它:
<ApolloProvider client={createApolloClient()}>
我希望这有帮助!