The future of state management
Peggy Rayzis
9.2K23

Perhaps I got rather lazy because I’ve been using MobX for a past year or so. I am failing to see a real value in this. I mean it’s surely nice to have a single way of handling state no matter of its origin, but that boilerplate that comes with it is rather mind-boggling. Don’t get me wrong, I love GraphQL and don’t ever want to touch any REST again, but this is just too much.

Let me do some comparison. This is an example from an article by James Munro. I think it would be better to cover the article which shows where this approach might shine instead of picking the simplest use case of all and over-engineer it.

const stateLink = withClientState({
cache,
resolvers: {
Mutation: {
incrementCounter: (_, args, { cache }) => {
const { counter } = cache.readQuery({
query: gql`
{
counter {
value
}
}
`
});

const data = {
counter: {
__typename: "Counter",
value: counter.value + 1
}
};

cache.writeData({ data });

return null;
}
}
},
defaults: {
counter: {
__typename: "Counter",
value: 1
}
}
});
Photo by Nick Fewings on Unsplash

Really? And that’s just resolver part, not the actual call for a change. That example could be more or less compared to action + reducer from Redux and even that would be way shorter and easier to read. With MobX (or rather with MST) all I have to do is this. I have a default value as a part of model, it’s easy to read and understand what it actually does just by looking at it once.

const Counter = types.model({
value: 1
})
.actions(self => ({
increment(inc = 1) {
self.value += inc
}
}))

To actually mutate that state with Apollo State it looks like this.

const IncrementButton = graphql(gql`
mutation incrementCounter {
incrementCounter @client
}
`)(
class extends Component {
onIncrementPressed = () => {
this.props.mutate({});
};

render() {
return <Button title="Increment" onPress={this.onIncrementPressed} />;
}
}
);

This is not too shabby for sure. It might even get better with render prop components for executing mutation, but still a bit verbose considering what it does. Comparison to MobX once again.

const IncrementButton = inject('counter')(({ counter })=> (
<Button title="Increment" onPress={counter.increment} />
))

And that’s it. Yes, I haven’t even used a class here because … why? The action is already bound and it generally reads so much better. See this article if you are interested in this more.

I don’t know. I love what has Apollo done for GraphQL and I am very grateful for it, but this approach just feels bad and I don’t understand why are people so excited about it. I am either missing out something here or it’s some strange bandwagon everyone is hopping onto for some reason :)