After having launched a couple of small React projects, I've grown to like it. Finally I have a couple excuses to use it in an access-controlled read/write context -- for my dayjob I'm rewriting a small buildbot and dashboard, and for the Detroit Ledger we want to basically rewrite the whole system piece by piece.
Whereas a few months ago my head was spinning when I thought of even doing a small app, I have put some time into figuring out what I want to focus on learning.
You can see what I've come up with so far in two repositories: my boilerplate, which is basically a way for me to keep notes, and gnl-react, which is all of that notetaking manifested in a new frontend for the Detroit Ledger.
One of the previous projects I'd built used Meteor and an early iteration of its React mixin, and basically I got spoiled by Meteor taking care of my app's state and updates. While it didn't turn out to work so great for everything -- being able to control the granularity of realtime subscriptions, and using them for everything -- I did find that the idea of having a single datastore for the whole app's state made sense.
On the API side of things, I've done some playing with GraphQL while writing a new prototype API for the Detroit Ledger. I found these two posts and basically got lost in a flurry of learning until finally being able to re-read them and make an informed decision!
How do you pass along authorization errors?
throw new Error() or attach an
errors: [Error] to every response that might get back errors? Here's an exmaple of someone using the latter pattern: https://github.com/jferrettiboke/react-auth-app-example/blob/master/server/src/typeDefs.js. The githunt react apollo demo app uses the former. Passing along an error to the client like this might make sense for something that is really bad, but for auth errors or whatever I'd rather just show a little toast and maybe have the option of persisting it to the next pageview.
https://github.com/JakeGinnivan/react-redux-notifications is one approach -- it's a redux middleware that listens for certain events & then renders a react component that you provide, and it handles some common style options.
In a form, you can do validation client side & keep things in react component state. But the results of mutations will come in at any point, so if an error comes along with the new query result, it might not have the error attached anymore. You can dispatch an event to add the error to the redux state, though -- this way, you can display a list of errors in a popup or whereever you want. I didn't really like how this felt, though, so I created an
Errors component which displays the current list of errors, a
setError action which can be called as a side effect from any part of the app, a
dismissError action that is called from within the
Errors component to remove an error. This way I have total control of how errors are displayed, and if needed I can add features to deal with certain messages differently. Maybe
Messages would be a better name. I can change that later on.
For styling notifications, I like the looks of react-notifications-system -- this lib would integrate cleanly with the reducer I've written so far.
https://hackernoon.com/graphql-tips-after-a-year-in-production-419341db52e3 has a bunch of ideas for how to harden a setup like this for production.
ES6 and 7 offer a few new features for copying and modifying objects in one step, but they don't cover what end up to be a few common use cases. React offered
react-addons-update, which has become its own non-react-dependent package immutability-helper. The old React docs cover common usage.
Some future blog posts:
- Should I stick with Apollo?
- How to do server-side rendering for JWT clients?
- What style management system to use?