FormidableLabs / redux-little-router

A tiny router for Redux that lets the URL do the talking.
MIT License
1.04k stars 114 forks source link

Discussion: trigger async action from via navigation/action #228

Open haf opened 7 years ago

haf commented 7 years ago

I'm thinking of ways to ensure a reload at a path inside the app works.

I have a list triggering an EDIT action, which then navigates to the details page.

Currently I fetch from /api/entity/${id} when that happens. But that's not a good solution to in-depth linking.

Do you 1) attach the URI to request to in the routes.js routing dictionary, or 2) do a regex match on the URI in an epic/saga on the side, or 3) something else – to ensure the right data is loaded on reload?

I'm leaning towards mapping entity URLs for each pathname/URI in the app and then having an epic fetch that.

Like so:

screen shot 2017-08-29 at 17 36 41
jcrben commented 6 years ago

It seems like the pattern floated about for running these types of things is at https://github.com/FormidableLabs/redux-little-router/issues/239 - @tptee is that the recommended pattern? the boilerplate at https://github.com/FormidableLabs/redux-little-router/tree/6165404bc5f2b6abd0d71e55b7887735d4ea280a#wiring-up-the-boilerplate doesn't have an example of an async action such as a server load.

redux-first-router has an interesting example in their boilerplate: https://github.com/faceyspacey/redux-first-router/tree/b98a645a7eb29e8c419bb8ea29582022d657be91#routesmap

haf commented 6 years ago
screen shot 2017-11-28 at 11 18 05

Turned out like this for me in the end. collection vs entity.

The issue with the first sample in #239 is that each route has to be listed in the switch, so it's both declarative and procedural at the same time.

In the second sample, of the new router lib, the issue is one of totality. They don't properly handle their return values, since async itself doesn't handle anything but fiber coordination.

Totality, meaning in this case, that all possible HTTP status codes and Content-Types should be properly handled in the JavaScript. Or in plain terms; if you don't it will crash you app in prod.

Here's my own version:

screen shot 2017-11-28 at 11 22 02

retry404 is a special-case filter (this epic only fetches entities and since we're eventually consistent, polling until <> 404 is the way to go), whilst selectFilter returns the current path's/state's request filter. A filter is a function from Send -> Send, where Send = Request -> Observable<Response>, and as such you can compose filters together like (in F#) let st = store.getState() in let! response = (retry404 >> selectFilter st) request. In the end we have a sender with content negotiation and retries built in as filters (Node.js people call them middleware, btw)

Then we dispatch a generic action just like in #239, depending on the result