apollo-client: Update reducer is not firing

I’m trying to get an update reducer to fire upon a successful mutation. However the reducer does not appear to get triggered, even though the round trip to the server was successful.

This is how I configured the reducer:

const ReducerTestWithData = compose(
  graphql(UpdateValueMutation, {
    props: ({ mutate }) => ({
      updateValue: (id, value) => mutate({ variables: {id, value} })
    }),
    options: (ownProps) => ({
      reducer: (prev, action) => {
        console.log("Reducer fired");
        return prev;
      }
    }),
  }),
  connect(
    (state, ownProps) => ({}),
    (dispatch, ownProps) => ({
      dispatch,
    }),
  ),
)(ReducerTest);

I’m wondering if there’s any extra configuration (for example when setting up the store) that I’ve missed, or is maybe the options stanza wrong?

I’ve stripped the example down to a bare bones runnable example (see below). In this example, the update is successful, but the reducer does not fire:

import React, { Component, PropTypes } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TouchableOpacity
} from 'react-native';

import { createStore, combineReducers, applyMiddleware} from 'redux';
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { ApolloProvider, graphql, compose } from 'react-apollo';
import { connect } from 'react-redux';
import gql from 'graphql-tag';

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

class ReducerTest extends Component {

  constructor(props) {
    super(props);
    this.updateValue = this.updateValue.bind(this);
  }

  updateValue() {
    this.props.updateValue(
      "101",
      "some_value"
    ).then(({ data }) => {
      if (!data.errors) {

        let { id, value } = data.updateValue;
        console.log("Successfully updated value (" + value + ") for id (" + id +")");

      } else {
        console.log("Application error: " + error);
      }
    }).catch((error) => {
      console.log("Server error: " + error);
    });
  }

  render() {
    return (
      <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
        <TouchableOpacity onPress={this.updateValue}>
          <Text>UPDATE VALUE</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

ReducerTest.propTypes = {
  updateValue: PropTypes.func.isRequired,
};

const UpdateValueMutation = gql`
  mutation updateValue($id: String!, $value: String!) {
    updateValue(id: $id, value: $value) {
      id
      value
    }
  }
`;

const ReducerTestWithData = compose(
  graphql(UpdateValueMutation, {
    props: ({ mutate }) => ({
      updateValue: (id, value) => mutate({ variables: {id, value} })
    }),
    options: (ownProps) => ({
      reducer: (prev, action) => {
        console.log("Reducer fired");
        return prev;
      }
    }),
  }),
  connect(
    (state, ownProps) => ({}),
    (dispatch, ownProps) => ({
      dispatch,
    }),
  ),
)(ReducerTest);

class ReducerTestContainer extends Component {

  constructor(props) {
    super(props);
    const networkInterface = createNetworkInterface({ uri: 'http://localhost:4000/api' });

    this.client = new ApolloClient({
      networkInterface,
      dataIdFromObject: (result) => {
        if (result.id && result.__typename) {
          return result.__typename + result.id;
        }
        return null;
      },
    });

    this.store = createStore(
      combineReducers({
        apollo: this.client.reducer(),
      }),
      compose(
        applyMiddleware(this.client.middleware()),
      )
    );
  }

  render() {
    return (
      <ApolloProvider store={this.store} client={this.client}>
        <ReducerTestWithData/>
      </ApolloProvider>
    );
  }
}

AppRegistry.registerComponent('reducer_test', () => ReducerTestContainer);

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 18 (3 by maintainers)

Most upvoted comments

@0x6e6562 For updating just a specific node (and not inserting to or removing from a list) I would recommend dataIdFromObject (I’d recommend using that instead of updateQueries or reducer whenever you can). If the updated node has the same global id, then Apollo Client will update that node in the cache, and all queries involving that node will be updated.

Since the original question has been solved, I’ll close this issue. If there’s an actual issue, feel free to open a new thread.