23

Graceful GraphQL with React Hooks and MobX

 5 years ago
source link: https://www.tuicool.com/articles/hit/6Fv2U3F
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Graceful GraphQL with React Hooks and MobX

GraphQL meets React Hooks and forms a powerful friendship. They should connect with MobX too!

GraphQL is definitely getting more and more attention and it’s well deserved. Raise your hand if you tried it and want to go back to fetching data from multiple endpoints. Nah, don’t worry, I think I know the answer :sunglasses:.

Apollo is the most common solution when it comes to GraphQL and I even dare to say that without them we wouldn’t be as far along as we are in GraphQL development. The community and technology they have built deserves :clap:.

When React Hooks came into the light , it was only a matter of days before the unofficial project react-apollo-hooks was published. I’ve immediately jumped on the wagon and have been enjoying it since then.

Just for fun compare these three approaches for executing mutations.

6FnI3uf.jpg!web

Ok, you had your fun, now let’s move on. The article is about something totally different … queries. Oh, and I’ve promised some MobX, haven’t I?

YNJr6vV.jpg!webYveUFfE.jpg!web
Photo by AK¥N Cakiner on  Unsplash

Running queries is essential to GraphQL. What would you do without your precious data? I am going to focus on the Hooks approach only since there are better resources describing the other two.

6FnI3uf.jpg!web

Nothing spectacular yet. Some people might object that data fetching shouldn’t be done inside the UI component. Sure, feel free to separate it if you like. Let’s focus on more pressing issues of the article.

There is a variable coming through props and passed to the query. When the value changes, a query gets re-executed. That’s cool so far and definitely beats using componentDidMount to execute fetch and subsequent shenanigans when you need to update it:stuck_out_tongue_winking_eye:.

Now imagine that the variable tag is not easily reachable. Perhaps it’s in some settings panel that’s not related to displaying the actual image. You most likely don’t want to be passing that up and down through like 10 or more layers, right? (That’s called prop drilling just for your reference.)

Wait, but this is supposed to be about MobX. Why don’t you…? Hold your horses, I will get there.

Let’s call the Context for the help here.

6FnI3uf.jpg!web

The SettingsProvider would be placed at some top-level to cover all components that might need it. Everything looks great and our RandomGiphy component will be re-rendered when we update settings.

Ouch! Did you just realize the same thing? Nothing?

Do you know what also happens when we update the settings? Every other component all the way down from SettingsProvider will be re-rendered! I will give you a moment to think about it…

Ok sure, in this silly example it won’t matter a bit. In a real application though, there might be some performance implications for sure.

Finally, it’s time to employ my beloved MobX to save the day!

6FnI3uf.jpg!web

For the SettingsProvider it makes sense to have some persistence, but I’ve left it out for brevity. Even if it were here, it wouldn't be re-rendered anytime soon, unless there is some other culprit even higher in the tree of course.

Also, notice that I haven’t separated the data and the state updater. The observable state can be mutated directly. Sure, it’s not always the brightest idea, and I encourage you to create actions for some level of abstraction if you like. Or just have a look at the brilliant mobx-state-tree .

The RandomGiphy is pretty much the same except it got wrapped into the observer HOC from the MobX family. It will take care of re-rendering the component (and nothing else) when tag is updated :heart_eyes:

Ok, we are done here. Have a nice day and see you again soon…

No, wait! We can do even better.We have the ability to make custom hooks. Why don’t we separate querying logic into one?

6FnI3uf.jpg!web

Once again, this is a fairly silly example, but such separation of concerns can surely be useful. Notice that we don’t need observer for our component anymore because that logic happens inside the hook, although it’s not as nice and declarative. Besides, such separation could prove useful for integration testing too .

And what about loading & error states?

The errors are somewhat simple. You can let it bubble up in a tree by throwing it and catching with error boundaries . You might want to send it to some reporting service or perhaps show an error toast? Or if this doesn’t fit your needs, just return an error from the hook and handle it in the component with some UI.

Loading is mostly just temporary for now. It’s fairly safe to assume that if null is returned from the hook, it means that data is still loading and that the UI should probably display a spinner. Later on, when React Suspense for data fetching gets some love, I am sure there will be some other ways we can only dream of :heart:.

Final result

I’ve prepared a fully working demo for you to see everything in action. It’s not some fancy app (I am not a designer), but for a showcase, it will do. There are some small additions to it not mentioned here. Feel free to experiment with it.

Warning: At this moment it seems there is some sort of bug. In some cases, when changing the input value, data gets fetched but the component is not re-rendered. See the issue for more details . One workaround is to keep using an observer HOC for the component, but I hope to find solution to this.

I hope you are starting to understand that MobX is a really powerful tool for optimizing your app renderings. And it’s super easy without the need to mess around with the Redux and similar tools to do basic stuff. If you are still hesitating, check out my other recent article on a similar topic.

Questions?

If you want to express your opinion or just ask some questions and you are a bit annoyed by Medium’s way, let’s do thatover at Twitter. Kudos to Dan Abramov for this idea used on his overreacted.io blog . Or go ahead to Spectrum if you like that more.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK