Skip to content

Handling async data by making reducers behave like Elm signals #1205

@Zacqary

Description

@Zacqary

Forgive me if this has already been figured out; I've looked through the Redux docs and at some middleware and I haven't found a solution myself.

Here's the problem I've had to solve:

  1. User action updates the Redux state of a property called metric.
  2. Re-render the view with the value of that metric, and populate a selection box with the metric's corresponding context options.
  3. Those context options need to be fetched asynchronously from the server. If we haven't cached the contexts for this metric yet, request them. Meanwhile, render a "loading" symbol in the selection box.
  4. Re-render the view once the contexts have been fetched

In Elm, this would be a simple act of making context a Signal. Since Redux recommends Elm-like architecture, I'd like to replicate that pattern.

I have a solution that I'm a little uncomfortable with. After the metric gets updated, it gets passed to the React view. The view sees that the store has no context for that metric yet, and then calls an action creator called requestContext. This uses redux-thunk to asynchronously fetch the contexts, and then dispatches an action to add those contexts to a lookup table in the store. After that, the view is re-rendered, and it can now look up state.context[state.metric].

But the thunk first has to dispatch an action to set those contexts to a value indicating that they're loading. Otherwise the view could keep requesting the contexts over and over again if it re-renders before they're fetched from the server.

So that's the problem: I'd much rather be able to keep that action dispatching/updating logic out of the view. I just want to pass a value to the view, and have it display that value, whether it's a loading state or retrieved data.

I'm not sure if redux-promise is an effective solution for this either — it seems to be about delaying the dispatch of an action just like redux-thunk, but with a different syntax.

I suppose the better solution would be for the reducer handling context to make the request, return a loading state, and then return the result of the request. But that would mean having to dispatch an action from the reducer, right? I don't think that's possible without middleware — maybe something like thunk (which exposes store.dispatch), but for reducers instead of actions?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions