Search code examples
reactjsgraphqlrelaymutation

Update Subcomponent with viewer after mutation in relay


I’m new to Relay (with reactjs) and have a problem with updating my UI after a commit mutation in the viewer. In my example I have a Salutation Component with the first name of the user and to simplify this, I put a input field right after the output of the name.

When the user changes the name in the textfield, I send this to my updatemutation and to the API. My problem is that I don’t know how to update the name above the input, after the new name was saved. Could anyone help me - what do I need to do in the updater?

Many thanks!

The "root"-Component:

import React, {Component} from 'react';
import {QueryRenderer, graphql} from 'react-relay';
import environment from 'app/settings/createRelayEnvironment';
import Salutation from 'app/components/dashboard/includes/Salutation';


const DashboardQuery = graphql`
    query DashboardQuery {
        viewer {
            ...Salutation_viewer
        }
    }
`;

class Dashboard extends Component {
    render() {
        return (
            <QueryRenderer
                environment={environment}
                query={DashboardQuery}
                render={({error, props}) => {
                    if (error) {
                        return <div>{error.message}</div>;
                    } else if (props) {
                        return (
                            <div>
                                <Salutation viewer={props.viewer}></Salutation>
                            </div>
                        );
                    }

                    return <div>Loading</div>;
                }}
            />
        );
    }
}

export default Dashboard;

The Salutation-component:

import React, {Component} from 'react';
import {createFragmentContainer, graphql} from 'react-relay';
import PropTypes from 'prop-types';
import UpdateDashboardMutation from 'app/mutations/UpdateDashboardMutation';


class Salutation extends Component {
    render() {
        return (
            <div className="salutation">
                <h2>Willkommen {this.props.viewer.firstName}</h2>
                <input type="text" onChange={this._onChange.bind(this)}/>
            </div>
        );
    }

    _onChange(event) {
        UpdateDashboardMutation(event.currentTarget.value);
    }
}

Salutation.propTypes = {
    viewer: PropTypes.object
};

export default createFragmentContainer(Salutation, graphql`
    fragment Salutation_viewer on Viewer {
        firstName
    }
`);

And the Updatemutation:

import {commitMutation, graphql} from 'react-relay';
import environment from 'app/settings/createRelayEnvironment';


const mutation = graphql`
    mutation UpdateDashboardMutation($input: UpdateDashboardMutationInput!) {
        updateDashboard(input: $input) {
            ok,
            errors {
                field,
                messages
            }
        }
    }
`;


function UpdateDashboardMutation(firstName) {
    commitMutation(
        environment,
        {
            mutation,
            variables: {
                input: {
                    firstName
                }
            },
            updater(store) {
                // what i have to do here?
            }
        }
    );
}

export default UpdateDashboardMutation;

Solution

  • Try:

    const viewer = store.getRootField('viewer');
    viewer.setValue(firstName, 'name');
    

    See https://facebook.github.io/relay/docs/en/relay-store for details.