
A Simple Way to Route with Redux - jlongster
http://jlongster.com/A-Simple-Way-to-Route-with-Redux
======
skrebbel
I suspect my knowledge is behind the times, but I never understood the appeal
of putting stuff like "current thread" in the app state at all. To me, it
makes much more sense if the stores (or the single data tree, in the redux
case) just contain the flat dumb data, and the URL is used to pick the
relevant data that the components need. This way, no state is duplicated
anywhere, the stores are dumb, and the URL is leading.

This is how most server side MVC frameworks work too, it makes server-side
rendering super simple (even with shared app state between users), it fits
with RESTful designs, it forces you to design state into URLs so users can
share links by definition, and so on. It just seems obvious to me.

But somehow, Flux and most things derived from it seem to disagree and insist
on storing the "this is what the user looks at right now" information in the
application state. To me, that hopelessly convolutes things. But I've been
wrong before and I'd like to learn.

Can anyone explain to me why that's better? I might just be a conservative,
grumpy old man here.

~~~
matt4077
There may be some state that belongs in the URL and some that doesn't. The
threat currently read should certainly be in the URL to facilitate
sharing/bookmarking etc. But, for example, the state of some checkboxes or a
dropdown or values in input element – while being part of state – don't feel
like they belong in the URL.

I've actually been struggling with some of these. For example, whether a
dropdown is expanded or not is state, but it just doesn't feel 'big' enough to
even be in the reflux store. Plus it turns out to be a major hassle to
implement such a dropdown, with actions firing the new state all the way up to
the store and the state then being passed down the whole chain of components.

Following redux orthodoxy here also precludes you from using existing
libraries (bootstrap/jquery) and kinda leads to reinventing the wheel. I had
no idea how much consideration a simple dropdown takes until I looked at the
bootstrap/jquery source for it.

~~~
guscost
For common components like Dropdowns, DatePickers, etc, I've been using Kendo
UI Core with a set of simple wrappers to make them (mostly) stateless:

[https://github.com/guscost/kendo-react-
wrappers](https://github.com/guscost/kendo-react-wrappers)

Perhaps not acceptable for performance-critical or first-class consumer-facing
UIs, but you get nice cross-browser compatibility and pre-built widgets that
can be surprisingly complex.

~~~
matt4077
So, if I see this correctly, these components save their state in a global
object, and that is supposed to persist state on re-renders? I get how this
can be considered somewhat 'dirty', but can you elaborate on the performance
implications?

~~~
guscost
The global KW object is just a namespace for the widget wrapper components.
You'd have to reference the Kendo UI Core library and then the KW.js script
before rendering your components containing e.g. <KW.DatePicker /> as in the
readme.

Internally the Kendo library is going to maintain its own state and manipulate
the DOM elements needed for each widget, and I only know a bit about how that
works. Most of these wrappers only run render() once because React would throw
all kinds of errors if it tried to diff the DOM inside the components.

Updates are handled in componentWillReceiveProps, and whenever the component
can be updated with the new props without destroying and recreating itself,
the updates happen via the Kendo API (after the wrapper checks if the new
value is different). This means that for common use cases these wrappers
should perform just about as well as the widgets do normally. Also every
controllable setting is exposed as a prop, and the props are synchronized on
every update. Props that are not passed in are reset to the defaults, meaning
these widgets should _appear_ stateless to the containing component.

The react-kendo project[0] uses some very cool introspection to provide full
support for all the Kendo widgets, and it looks like it should be reliable and
stateless. However it destroys and rebuilds the widget on every update. While
that probably isn't going to be a huge performance hit it certainly makes a
difference.

[https://github.com/tjwebb/react-kendo](https://github.com/tjwebb/react-kendo)

------
cubano
Call me old (yes I am!) fashioned, but would it be too much to ask to see some
sort of example app using said widget in the post?

This is the second article I've been interested in today here on HN that
seems, to me at least, to go on and on extolling the virtues of said
framework/extension/etc, and in the end gives absolutely no hint of how to use
it.

Yes yes I know...farts like me are behind the curve/too slow/fat/old/stupid
etc to understand all this modernity, but really, is it too much to ask for a
small example of the Greatness?

~~~
Lazare
Very fair point, however...

...in this case, it's not a widget, but a routing library. Actually a slightly
nicer wrapping library around the same base routing library used by basically
every React project, which means that for the user, it'll look exactly like
every project that _doesn 't_ use it too. The only thing to "see" is basically
the API docs.

(That being said, maybe that could be made clearer in the blog post...?)

~~~
jlongster
This post was strictly intended for current users of redux and react-router.
That could be included yes, but I have limited time and I'd rather publish
blog posts rather than languish in my "drafts" folder. I can add a few things
to this though.

------
sideproject
Javacript moves fast (everybody knows that...). React and the tools around
also move very quickly.

I've been delaying learning React for awhile. After a period of ranting about
"another JS library, another JS tool etc etc!!", I got tired of my ranting and
have been giving a decent go at picking up React and a myriad of related tools
(webpack, flux, react-router...).

It turns out, if you have some experience of framework, whether it be
AngularJS or Backbone (I come from BackboneJS and Marionette background), it
doesn't take you too long to learn these things.

I signed up for Egghead, searched around for awhile for the latest relevant
tutorials, opened up many Chrome tabs and jumped around different places, but
after a week, things are falling into places (JOY!).

Learning part is frustrating, because there are references to old versions,
old tutorials and you have to somehow mine through to make sense for yourself.
But what isn't thesedays?

I haven't picked up redux properly yet, but now I get Flux, I don't think
it'll take too long before applying it. Redux Router? Bring it on!!

------
iamlacroix
I recently switched to this library from Redux Router for a project, after
having trouble with server-side routing.

It really is simple, as stated in his title, and I would definitely recommend
it if anyone is using Redux and React Router.

~~~
Lazare
I've been struggling with redux-router all week, and was just about to spend
today trying to switch to this project. Glad to hear your experience. :)

~~~
AndrusAsumets
Yeah, same here. Almost decided to ditch the whole redux-router for good
before I saw this thread.

------
losvedir
As someone who's mainly just used react for simple components, when is the
right time to think about pulling in redux? I'm getting by with just react,
but it seems like at some complexity level everyone recommends a flux library
(and mostly redux these days). Is it when you have multiple component trees on
the page? When AJAX requests are involved? Or do people familiar with redux
just drop it in from the very start even on simple components?

~~~
insin
Dan Abramov wrote a blog post a while back with a bunch of "You might need
Flux if..." use cases, which might be handy: [https://medium.com/swlh/the-
case-for-flux-379b7d1982c6](https://medium.com/swlh/the-case-for-
flux-379b7d1982c6)

------
theduro
This library lack some of the super powerful features that really made me fall
in love with redux-router. Being able to get access to params was huge, and
having action creators to pushState and replaceState was also huge.

~~~
jlongster
`updatePath` is an action creator, and there's a PR to rename it to `pushPath`
and add `replacePath`. And you shouldn't access route params outside of a
router component anyway.

(EDIT: ok, the last statement was a simplification. But generally you don't
need to, but you could manually move data into the state if you needed to)

~~~
theduro
I get that, but still no access to params and the ability to change them is
still a boon for me. I often will use stand to store some basic state for deep
linking certain views. For example a data grid and the sort or filter options.
I was able to very elegantly execute this with redux-router and its full
exposure of the entire route object and API pairity to pushState and
replaceState

~~~
jlongster
That's great! Keep using redux-router then. I think you'd find that there's
another pattern that works too, but there are multiple ways to do it.

------
jiyinyiyong
We got a router too for the same reason that Redux is complicated(and at that
time redux-router was not released)

[https://github.com/teambition/router-
view](https://github.com/teambition/router-view)

And it's demonstrated at here:

[http://r.nodejs-china.org/#/](http://r.nodejs-china.org/#/)

------
rattray
There's an open issue to replace redux-router with this package:

[https://github.com/rackt/redux-
router/issues/172](https://github.com/rackt/redux-router/issues/172)

------
capkutay
I personally agree with and admire the methodology behind Redux, but I'm
cautious about using it because it's right at the bleeding edge of web
technologies (which we all know are rapidly changing).

------
Kiro
So why so we want the URL in the state? What's the use case?

~~~
jgautsch
One use case of having URL in the state (from the lib's README:
[https://github.com/jlongster/redux-simple-
router](https://github.com/jlongster/redux-simple-router)) is that you can
snapshot/serialize the app state, and load it up later and see the same thing.
This can be useful for development and debugging.

It's also worth mentioning that this lib also provides a really useful action
creator- updatePath(). It allows you to navigate from other action creators,
for example, in response to a successful AJAX call. You could achieve that a
couple other ways as well, but this is the simplest/cleanest way I've seen so
far.

~~~
Kiro
Thanks. updatePath is actually something I've been missing so that's great.

------
asimjalis
Nice pictures. How did you make them?

~~~
lauritzsh
I am curious too, really refreshing look. I would guess it's hand-drawn with
something like Paper, the "smudges" reminds me of that app.

[https://www.fiftythree.com/paper](https://www.fiftythree.com/paper)

------
rattray
> This is what redux-router attempts to do, but it's very complicated and
> prone to bugs.

redux-router is still in beta, so this isn't entirely fair.

~~~
cjhveal
I think the point is that serializing the entire react-router state into a
redux store is in itself barking up the wrong tree, not that their approach is
complicated or implemented in a buggy manner, per se.

------
marknutter
It's disappointing that this depends on React's router, considering Redux is
an agnostic framework. Unless I'm reading something wrong here..

~~~
kevan
From the post:

> After integrating redux and react-router in my site, I extracted my solution
> to a new project: redux-simple-router. The goal is simple: let react-router
> do all the work. They have already developed very elegant APIs for
> implementing routing components, and you should just use them.

The explicit goal of the project is to take advantage of react-router's
existing tools when used with redux, it doesn't make any sense to lament that
it depends on react-router.

~~~
marknutter
Then why not call the project redux-simple-react-router or something to that
effect, given that it's written for an agnostic library but has a hard
dependency on a third library? It's easy to get caught up in one's own bubble
but you should be aware that there are plenty of people out there who don't
use React but like some of the libraries and patterns that came out of that
community.

