nareshbhatia / graphql-bookstore

Example demonstrating the use of GraphQL to implement a rich domain with multiple entities and relationships
121 stars 19 forks source link

Adding a new item from the client does not update the view #1

Closed nareshbhatia closed 5 years ago

nareshbhatia commented 5 years ago

A create mutation is not updating the view. Specifically, a mutation followed by a writeQuery updates the cache but the component using the query is not refreshed. Here's the related issue in the apollo-client repo. (Note that update mutations are working well.)

To reproduce this issue

# Checkout the following tag
git checkout 5-mutations-client

# Start the server in shell 1
cd apollo-bookstore-server
yarn
yarn dev

# Start the client in shell 2
cd apollo-bookstore-client
yarn
yarn start

Point your browser to http://localhost:3000/

Create a new author. While the author is added to the cache, the Author List is not refreshed.

Relavant code

The relavant code can be found here:

<Mutation mutation={CREATE_AUTHOR}>
    {createAuthor => (
        <AuthorDialog
            author={this.editedAuthor}
            onSave={author => {
                createAuthor({
                    variables: {
                        name: author.name
                    },
                    // Update AuthorsQuery in Apollo cache
                    // Needed only in this "Create" case
                    // TODO: Does not work. See
                    // https://github.com/apollographql/apollo-client/issues/2415
                    update: (
                        store,
                        { data: { createAuthor } }
                    ) => {
                        const data = store.readQuery({
                            query: GET_AUTHORS
                        }) as any;
                        data.authors.push(createAuthor);
                        store.writeQuery({
                            query: GET_AUTHORS,
                            data
                        });
                    }
                });
                this.hideAuthorDialog();
            }}
            onCancel={this.hideAuthorDialog}
        />
    )}
</Mutation>
nareshbhatia commented 5 years ago

Fixed.

AuthorsPanel was not updating because MobX observer prevents re-renderings when the props of a component have only shallowly changed. See following rule in MobX docs:

observer also prevents re-renderings when the props of the component have only shallowly changed, which makes a lot of sense if the data passed into the component is reactive. This behavior is similar to React PureComponent, except that state changes are still always processed. If a component provides its own shouldComponentUpdate, that one takes precedence.

We only shallowly changed the authors prop by pushing to it. Hence a re-render was not triggered. To fix this we are now sending the full data object returned by the query to AuthorsPanel