Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea: Simplify and encapsulate mutation calls? #824

Closed
ianstormtaylor opened this issue Feb 10, 2016 · 2 comments
Closed

Idea: Simplify and encapsulate mutation calls? #824

ianstormtaylor opened this issue Feb 10, 2016 · 2 comments

Comments

@ianstormtaylor
Copy link

There’s a lot of boilerplate involved to invoke a single mutation with the current API. And each of the containers needs to be aware of the singleton Relay.Store in each of their calls. It would be easy to create a bit of convenience on createContainer that reduces the boilerplate, and allows for an easy way to remove the Relay.Store singleton dependency in the future.

Using the like button example from the docs, it would change from calling the singleton directly:

class LikeButton extends React.Component {
  _handleLike = () => {
    Relay.Store.commitUpdate(new LikeStoryMutation({story: this.props.story}));
  }
  render() {
    return (
      <div>
        {this.props.story.viewerDoesLike
          ? 'You like this'
          : <button onClick={this._handleLike}>Like this</button>
        }
      </div>
    );
  }
}

module.exports = Relay.createContainer(LikeButton, {
  fragments: {
    story: () => Relay.QL`
      fragment on Story {
        viewerDoesLike,
        ${LikeStoryMutation.getFragment('story')},
      }
    `,
  },
});

Into calling a method on this.props.relay, which is a nicer, thin wrapper over interacting with the raw mutations objects and the store itself. In the future, this could allow the Store to actually be passed down the Containers tree (via context, like Redux does it), instead of relying on a singleton:

class LikeButton extends React.Component {
  _handleLike = () => {
    this.context.relay.likeStory({ story: this.props.story });
  }
  render() {
    return (
      <div>
        {this.props.story.viewerDoesLike
          ? 'You like this'
          : <button onClick={this._handleLike}>Like this</button>
        }
      </div>
    );
  }
}

module.exports = Relay.createContainer(LikeButton, {
  fragments: {
    story: () => Relay.QL`
      fragment on Story {
        viewerDoesLike,
        ${LikeStoryMutation.getFragment('story')},
      }
    `,
  },

  mutations: {
    likeStory: LikeStoryMutation
  }
});

Just an idea!

@josephsavona
Copy link
Contributor

In the future, this could allow the Store to actually be passed down the Containers tree

We're gradually transitioning from singletons and globals to fully encapsulated state. As of last week, Relay does pass an instance of RelayContext via the React context, and containers use this to access data. As part of this we'll change the mutations API to remove the RelayStore singleton, and will likely end up with something like this.props.relay.commitUpdate(...) (allowing users to locally name mutations doesn't seem to add much value and instead makes name collisions likely and code grepping harder).

We're tracking progress of all that at #558, so let's merge this discussion there.

@ianstormtaylor
Copy link
Author

Ah awesome, I hadn't found that meta issue yet, doh! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants