如何在Redux Reducer中使用GraphQL Mutations

时间:2017-11-09 13:32:30

标签: reactjs redux graphql create-react-app

我在这里有一个无状态反应函数,我很乐意用减速器调用我的突变。注意,调用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函数。

1 个答案:

答案 0 :(得分:1)

一些想法......

首先,reducers不应该改变数据或进行异步调用。它们是纯粹的功能而没有副作用。

暂时将GraphQL从图片中删除并假设您只有一个REST调用,您通常会在Action Creator或类似内容中进行变异。 Redux中的Action Creators本质上是同步的,因此您可以使用Redux ThunksRedux 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()}>

我希望这有帮助!