Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save faceyspacey/1996331cbbe78c3c23a043f63d298534 to your computer and use it in GitHub Desktop.
Save faceyspacey/1996331cbbe78c3c23a043f63d298534 to your computer and use it in GitHub Desktop.
title date headerImage keywords
redux-first-router - Just dispatch actions - Interview with James Gillmore
2017-xx-xx
/assets/img/XXX.jpg
interview

redux-first-router flow chart

TODO: I'll fill this up and link to your Twitter (@faceyspacey)

Can you tell a bit about yourself?

I've tried to stay quiet and keep it about the code rather than myself. But perhaps now is a good time.

Basically I started 12 years ago (2005) by hiring other developers to build things. I worked at a music studio in Time Square, NYC and hired developers to build websites for our clients, and eventually got into the MySpace spamming thing lol. I had been doing a lot of audio engineering, but soon realized my talents were best more directly applied to "technology." My dreams of becoming a famous beat-maker never came true lol.

So I jumped ship, started my boutique webdev agency, FaceySpacey Technologies (2007), got myself into trouble completing products on time for clients, and became a coder as a matter of necessity (2010). The rest is history :). A very long history of self-mastery (via programming and in the real world).

James Gillmore James Gillmore

How would you describe redux-first-router to someone who has never heard of it?

Redux-First Router is something that should have existed long ago, but because the React Community at the time got caught up with throwing out so much ancient wisdom, was skipped over. Redux-First Router completes the triumverate of the MVC, adding the "C" to the equation (where Redux is the "M" and React the "V"). Basically, it was as if nobody wanted to hear the letters MVC again. It's anathema to me too, but it is what it is.

It also kills the "everything is a component" concept when it comes to routes. It's now correctly: "everything is state" and routes are 100% in sync with actions to trigger that state; your view layer (components) just render from state as they should.

How does redux-first-router work?

You mean what does RFR actually do? It URL-izes your actions, dispatching them as a result of visiting URLs. Conversely, it changes the address bar in response to [matching] actions.

What's special about it is--and the very significant thing that was never done before--is that the actions dispatched have a unique type that only the given kind of URL have. This is unique because previous attempts at Redux routing (such as redux-little-router) dispatch actions that all have the same type--the equivalent of: LOCATION_CHANGED. Then you have to dig through lots of information nested in that action to figure out what really happened. It wasn't conducive to switching over types as is idiomatic in reducers.

As obvious as it sounds, having a type that is as informative as actions you manually dispatch is the key ingredient that finally makes routing seamless for Redux apps.

Oh yea, one other thing: because of how unhelpful other Redux routing solutions' actions were, you ended up using the same misplaced <Route /> components you're used to from React Router. I mean you didn't just "end up" using them--they were the only way to get things done, and were supplied by said packages. These packages promoted their own version of <Route />, rather than take advantage of how Redux removes state from the view layer.

Can you describe a bit more where <Route /> components went?

Initial attempts at Redux routing still drank the React Router Kool Aid that "everything is a component." As one of our initial users, @kmcclosk put it, "cargo culting the same React Router stuff as everyone else just didn't feel right, felt leaky, felt hacky."

The fact of the matter is that keeping any state (especially URL state) in the View layer has been an anti-pattern for a long time now, yet somehow React convinced us that React was the exception. It makes sense when you don't have Redux (or other UI database). But when you do, a lot more powerful opportunities unveil themselves to you.

<Route /> is for developers, for whom Redux is still out of reach. Contrary to how easy seasoned developers may feel Redux is, it's definitely hard for novice and even intermediate developers. So I think <Route /> still makes sense for a large category of users, but for "power users" Redux-First Router kills the <Route /> component as well as the "state-within-the-view-layer" anti-pattern. There I said it :)

How does redux-first-router differ from the other solutions?

Well, I already described the key difference between redux-little-router, but really that's only the tip of the ice berg. Redux-First Router brings it! I hate to make a comparison by plainly listing a longer set of features, but I'll say this: everything you do with Redux-First Router is in a way that mirrors the terminology and thinking of Redux itself. The primary example is the thunk option attached to routes--it has the same api as used with redux-thunk, i.e. the dispatch and getState arguments.

In addition, it's about what Redux-First Router stands for (it's "philosophy"). The fact that from the start it doesn't have you using <Route /> components and forces you to get the most out of Redux is a meaningful thing. Philosophy is meaningful. The same way all the contracts Dan Abramov enforced on us lol have made our lives easier.

Another fun fact: since the initial release of RFR, redux-little-router has taken a few RFR ideas to heart, such as removing re-rendering the entire app on location change like React Router still does. They've also moved toward promoting an approach without their <Fragment /> component, which is what they call React Router's <Route />. It's harder to do than with RFR and a lot less idiomatic in terms of your reducers, but it's a good signal of the signficance of the movement.

That all said, I'll indulge for a second--here's a quick list of the more unique and powerful things you can do with Redux-First Router:

  • route-triggered data-fetching
  • prefetching of (both chunks + data!)
  • React Native support (Android BackHandler, Deep Linking, Push Notifications)
  • sick stuff to make React Navigation actually work with Redux (this is really our best stuff which you'll be hearing about soon)
  • top notch SSR idioms
  • And absolutely everything you'd expect (redirects, 404s, scroll restoration, components, automatic document.title management, page-leave confirmations, dynamic route adding for code-splitting, history entries state, the list goes on...)

Most attempts at redux-specific routing have been pretty bare bones and never got around to all the necessary "rounding" to make it a full-featured solution. While there's always some feature that will need to be added, RFR is something I've committed to for the community. So no no expense has been spared!

Why did you develop redux-first-router?

Here's what I haven't told anyone and SurviveJS is the first to hear it: I actually was a relative newcomer to React (December 2015). I decided to skip straight to React Native (so I could skip mastering Webpack and all the related choices). I had a client project I had to build with a deadline. I jumped right in and built it using Redux. Near the end of the app I had to add deep linking and push notifications. So I wanted to find a way to make the app URL-driven without changing much code. I began looking into other redux routing solutions for RN, and since those weren't doing the trick, I decided to check out what they were doing on plain web.

I then realized there wasn't anything anywhere that allowed you to build your Redux app in a URL-independent way, yet while still having support for URLs. At that point it occurred to me that the obvious solution was to make your regular flux standard actions somehow be representative of URLs.

That's where the whole "action types as paths" concept was born.

It's really not all that complicated of a thing to do, so I was surprised that nobody had taken that route yet. Either way, that was just the beginning, and Redux-First Router is almost a year old now--so a lot more has been added to make it more than just a basic routing mechanism. As I wrote in the pre-release article, it's "powerful" not "little."

Just last week it reached "feature complete." As I described in that article, routing isn't a complicated computer science problem--the challenge is that there are so many things related to it. I.e. the router has a good claim to coupling many things to it (data-fetching, code-splitting, prefetching data + imports, SSR, redirects, React Native, etc). Building all that becomes quite a time-consuming endeavor, especially if you want to build it in a general enough way that such a package can displace the many homegrown routers. I think Redux-First Router has accomplished that and as a result will hopefully become the obvious solution for Redux apps.

...by the way, how the story ended was I built the router and had to change almost no code. Since all my actions were Flux Standard Actions with payload objects, it was only a matter of setting up the routing config, and then doing a bit of changes in reducers.

That's very interesting. Tell me more about not having to change your code??

Well, the concept is essentially that you have less actions when using RFR (which is very good thing by the way, given how outa-control the number of actions can become). Instead of having one action to show a drawer, and another action to close it (e.g 'OPEN_DRAWER' and 'CLOSE_DRAWER'), you simply have 'FEED' and 'NOTIFICATIONS' which you'll need anyway. Then in the reducers, you must add some "tear down" code to open and close the drawer when you visit these routes. I.e. when you visit 'NOTIFICATIONS' the drawerOpen reducer is true and when you visit 'FEED' (and essentially all unrelated actions drawerOpen is false.

Here's an example taken from the RFR solving the 80% use-case for Middleware article:

old way with lots of setter actions: oldredcuer

new way with less actions and smarter/fatter reducers: newreducer notice your reducers do more what I call "tear down" now

So that's basically all I had to do--change my reducers, remove unnecessary actions being dispatched and make my reducers respond intelligently to a wider variety of actions, and voila! I now had URLs and could deep link into my app in record timing as far as application code was concerned.

What next?

I've been working on completing my Universal product line. That will have some exciting connections to RFR. The hint is the word "prefetching." My overall main priority has been buiding "Next.js for the rest of us." I.e. the frameworkless approach to the best features from Next.js.

Next.js is great, but very few "power users" want to get locked in their walled garden. So by the time I'm done with my initial vision, the only reason to use Next.js will be because Webpack configuration is either too much for you or just something you rather not deal with. For truly professional apps, I can't see how seasoned developers would want it any other way. When it comes down to it, and if you're going for the top spot in your given market, you want complete customization available to you.

What does the future look like for redux-first-router and web development in general? Can you see any particular trends?

Simultaneous SSR + Code Splitting will become big. It's been a gritty time-consuming problem none have wanted to solve generally. My view is that the SPA is dead, and if you're not simultaneously splitting + server-rendering you're doing it "wrong." Traffic from google is the biggest driver for so many businesses, and a key component of basically all online/digital businesses--so to go without SSR is a mistake. And since the tools we are using these days are so heavy in terms of bytes--not splitting is perhaps an even bigger mistake. You gotta do both together.

By the way, not splitting doesn't just increase bounce rates, it also compounds the google problem, since google likes fast sites.

Until now, doing both SSR + Splitting has been a hair-pulling experience. Most just gave up. I won't get into the nitty gritty of what the challenge is today. But you can read my code cracked for SSR + Splitting article to learn why.

Oh and by the way, SSR with Redux-First Router is basicaly the most idiomatic Redux has ever been on the server. And since the way my Universal product line works regardless of what router you use, simultaneous SSR + Splitting is a dream with RFR. There is still some stuff left to do, and if you've heard that "splitting isn't related to routing," you've been misled. To do it at the highest level, you need to do prefetching. Prefetching is the connection to the router. Prefetching allows you to code-split and serve the most minimal set of bytes without your users even know you're doing so.

So the connection between the router and splitting is that you need a simple interface to specify which route to prefetch. That's all. RFR is the first solution that really does this. Next.js has <Link prefetch />--RFR has something far more powerful: automatic pre-fetching based on your current state, i.e. the current page a user is on, as recorded in Redux state. There's a one-time setup, but once you do, potential next routes will be pre-fetched.

There's one final thing to know about how RFR prefetching works: not just the "chunk" is prefetched, but the data from your route thunks as well!

What advice would you give to programmers getting into web development?

Question your intentions before you do anything. You'll waste your time doing the wrong thing with intentions that are likely to shift and evolve.

The paradox is it takes a long time to reach the sort of maturity where your intentions become "better." I started out in the game, not as a developer, but an entrepreneur wanting to build an empire. Reality has long since kicked my ass, I forced myself to become a coder to dig myself out of a hole, and the rest is history. That is to say, a long, VERY LONG, history lol. Mastering this craft is a time-consuming thing. And it's not about passion. I like to think of myself as a straight-shooter cowboy type with clarity of vision--sure I have passions for software, but it's more about the natural enthusiasm for creation/conception in general. And to really take the thought home, the truth is I enjoy other things outside of staring at a screen far more. For me it's about being a craftsman as a matter of maturity and integrity. To pay the bills, create value, and make real the stuff that only exists in my mind as I'm innately compelled to do.

I've built the open source stuff I've built primarily because I refused to go another project without these boxes checked.

Also, don't focus on open source. If you do, make sure your intentions are truly pure, and it makes sense for the juncture you're currently at. For me, I have things I plan to create, and for the timebeing I have the luxury to go the long first-principled route, which happens to align with open source contribution. After all, getting your creations (creations you yourself actually use) in front of the most people is what it's all about.

And if your intention is to build an empire and "change the world!", I sincerely ask you to question what that is really about for you. Most of the things we're building, someone else will build in a matter of time. The world doesn't need you to change it. That's all I'll say about that for now.

Doing what's natural for you is the most important thing. Forcing anything will lead to bad results. But we're only human, and is more often than not a core aspect of our journey to getting somewhere where we no longer force things.

So my advice to new programmers is: skip college lol, get yourself into a jam (or 2 or 3 or more lol) where you have to complete a product, and force yourself to become a better a programmer as the only option you [perceive you] have. Then after you know a thing or two with conviction, build that thing only you have the unique insights to build. All I can do is tell my story :)

Who should I interview next?

Truth is I've been so siloed so long as a lone-wolf programmer, I don't know enough programmers. In fact, I know none in real life. I'm trying to think of an up-and-comer, but you already did Ives from CodeSandBox. I might have to get back to you on this one, as I like to give answers I feel strongly about...Interview someone who's leading the serverless charge when it comes to React. That's another trend that will explode soon as a few more puzzle pieces come together. Perhaps the Dawson guys. I haven't tried it yet, but I'd love to see serverless made stupid simple for the React crowd and they seem to be on that path.

...Oh, here's who you should interview:

@nchanged from FuseBox

Perhaps I have an addiction to debunking stale solutions--and even though I get a tremendous amount of value from Webpack--I'd love to see it built from the ground-up, and everything somehow made a lot simpler while still being flexible. I know I'm not a lone in that feeling. FuseBox seems to show that promise, but perhaps it's easier said than done.

Any last remarks?

If you've ever felt Redux was due a routing solution native to its workflow, give Redux-First Router a try :)

Conclusion

TODO: I'll fill this up, thank, and link. Feel free to add resources here.

If you'd like to see Redux-First Router in action now, you can try it right here:

<iframe src="https://codesandbox.io/embed/github/faceyspacey/redux-first-router-codesandbox/tree/master/?module=%2FroutesMap.js" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe>

And here's the chronological history of how my 2 product lines have been progressing thus far:

Redux-First Router:

Universal:

Repos:

If you find value in either product line, don't forget to star and tweet to let other developers know!

Thanks for the interview James!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment