Live data from Hacker News

Redesigning Redux

medium.com

61–70 of 88 posts

Re: Redesigning Redux

#61
post #40

Earlier quoted context omitted.

I missed the part where you explained why changing the reducer to an object with methods would bring any benefits, or what's bad about message passing (it seems to me off the top of my head that changing this would at the very least, break redux observable as it currently works)

Direct function calls would at least make it easier to step through the code in the debugger, I imagine.

I feel like this benefit is more theoretical than practical owing to redux devtools, which offers a very similar experience of seeing what's been executed, perhaps even superior in some ways since you can see "everything" that's happening (with respect to the redux store), though you could probably create a similar thing without message passing

Re: Redesigning Redux

#62
post #37
post #35

Isn’t one of the points of redux to decouple actions from reducers? How would you implement multiple reducers responding to a single action if your actions are tied to a reducer with a namespace?

This can be done using Subscriptions [1]. I have another problem with this library, which is relying on singleton pattern for communication. This way, you cannot have more than one rematch instance in one application, which can be limiting. It also makes reasoning more difficult. [1] https://github.com/rematch/rematch/blob/master/plugins/subsc...

Ahh thanks, I was lazy and didn’t go looking for an answer. Though this line seems a bit odd..

> In this case, subscriptions avoid the need of coupling the auth model to the profile model. Profile simply listens to an action.

I guess it’s no different to using “vanilla” redux actions but because actions contain the reducer namespace then it’s inherently coupled to another model isn’t it?

Re: Redesigning Redux

#63

Is Redux too complex? That's the central argument this article makes but I find it to be patently false. What drew me to redux was its simplicity: Abramov said from the beginning that it's not anything you can't code yourself, it just provides a thin framework around making changes to some base state object. Its main strength (to me) is that it forces developers to think about state changes as mutations rather than r…

It's too much boilerplate. In my current project, I have to describe one action 7 times: 1. The constant var `const ACTION_NAME = ...` 2. The constant's value `... = Symbol('ACTION_NAME')` 3. The "action creator" function `const doAction = arg => ...` (extra creativity to add a verb here?) 4. The action creator's return struct: `... => ({ type: ACTION_NAME, payload: arg })` 5. The reducer switch clause `case ACTION N…

It's just javascript... when I'm writing a redux-backed app I will often abstract out commonly repeated patterns in action creators and reducers. Every project is different so I just wait until things start looking predictable and refactor. Not trying to be snarky, I just see this a lot at work; people seem to be locked in to the patterns used in the redux documentation and never attempt to rewrite it as they would any other part of their app. It's quite simple (especially if you are using ES6 with its destructuring assignment) to write a function that takes an action type and a function body that eliminates most of the boilerplate.

Re: Redesigning Redux

#64
post #54
post #30

Earlier quoted context omitted.

> full, serializable application state Perhaps I'm dense, but you can serialize the current running state of a Promise in redux-thunk?

One approach is to write a reducer which has `isWaiting`, `error`, `finished` bools (in addition to whatever data said promise eventually modifies), or something similar, and programmatically update them in your actions/thunks. This effectively tracks the state of the promise (resolved/not resolved, error).I think the Flux "standard action" puts something similar in the action object - not sure what they do with it t…

I always put a `pending` property on the `meta` object, and any component that needs to show network status can just check that property on every render cycle. Aside from requiring some extra utility functions in the reducers to prevent having to updating `pending` for every state of the request it's rock solid and I haven't ever encountered a situation where it wouldn't work. You can get a _lot_ of mileage out of conforming to the FSA standard[1]; network status goes in meta, and errors are always handled the same way.

[1] https://github.com/redux-utilities/flux-standard-action

Re: Redesigning Redux

#65
Nothing on this project solves the real problems and introduces different ones, like how to have a reducer respond to different actions. My quibble with React is that when you get into moderately complicated forms, you start sprinkling stuff all over the place to get the desired output. Take for instance the most popular form library, redux-form. It's very heavy on it's own way of doing things, and there's a lot of stuff you have to know about it to be able to read into what the hell is going on, and it's hard to keep shit in the same place. Reselect is also very heavy handed for what it does. I NEVER needed anything like reselect before redux, and it kinda went alright! In my experience, for any reasonable development with redux you have to introduce: reselect, redux-form, thunk, some sort of immutability (immutable or redux-orm), a sprinkle of compromises and plenty of boilerplate, or roll your own magic util functions (i actually rolled my own very similar stuff to rematch, for quick and dirty stuff). When you summarise all that, it's really not that simple anymore! By the time you get through all of that, you might aswell pick up angular with the added benefit of clearer best practices, nicer dependency injection (oh, but react calls it context so it's cooler!), familiarity and type safety.

It's kinda funny how redux succeeded with such heavy concepts, which is normally not the case. This is still a mistery to me.

Oh and don't get me started on HOC. Want a tooltip over your component? Sure, wrap it in tooltip HOC! Sooo much nicer than directives!

Re: Redesigning Redux

#66
post #59

Earlier quoted context omitted.

Thunk is not about storing async state in the datastore, it's more akin to multithreading in my opinion. In backend, you might spin up a thread to do expensive operation like API access, and that thread has it's own database connection, to read and persist data. With thunk, you dispatch a thunk-ed action to do expensive operation like fetching data from backend, and that action has it's own access to redux in form of…

How do you test the code being run inside the Redux store? How do you mock your API client?

A thunk action `fetchData` would return a `(dispatch, getState) => {}` function. You call that with `getState` that would return your fixtures, and verify that `dispatch` gets called as expected. For API, I use jest and mock out imported functions.

Re: Redesigning Redux

#67
post #54
post #30

Earlier quoted context omitted.

> full, serializable application state Perhaps I'm dense, but you can serialize the current running state of a Promise in redux-thunk?

One approach is to write a reducer which has `isWaiting`, `error`, `finished` bools (in addition to whatever data said promise eventually modifies), or something similar, and programmatically update them in your actions/thunks. This effectively tracks the state of the promise (resolved/not resolved, error).I think the Flux "standard action" puts something similar in the action object - not sure what they do with it t…

Yeah I get that, but then the application state isn't serialized in a usable form. If you re-load that state, you have half-open, "pending" operations.

If an idea of Redux is that serializable state is a good thing, then redux-thunk seems inimical to that.

Re: Redesigning Redux

#68

Earlier quoted context omitted.

A functional programming rosetta stone? Sounds challenging and interesting!

Hah. I just meant maybe a blog post that maps the terms I use in JavaScript land with math land. Ie. "it's not a reducer it's a functormonadicfoobar"

Thanks for the idea. Should make a fun series of posts for my blog assuming there isn't prior art on the subject.

Re: Redesigning Redux

#69

Earlier quoted context omitted.

> The strength of redux is that all your interactions with it are through functions I think it's the other way around: The greatest weakness of Redux is that (unnecessarily) message passing instead of function calls are used. Why do a `store.dispatch({type: 'INCREMENT', value: 10})` when it could be a `store.count.increment(10)`? In basically all cases every action is handled by exactly one reducer so just let the re…

One of the original reasons for message passing is that multiple reducers can respond to the same action. There have been many libraries since the beginning that try to shrink that relationship (ex reducks), but I never understood it, my code is replete with multiple responders.

> my code is replete with multiple responders

Thanks for your input! Do you mind giving 2-3 examples of good uses of multiple reducers for the same action?

Re: Redesigning Redux

#70
post #63

Earlier quoted context omitted.

It's too much boilerplate. In my current project, I have to describe one action 7 times: 1. The constant var `const ACTION_NAME = ...` 2. The constant's value `... = Symbol('ACTION_NAME')` 3. The "action creator" function `const doAction = arg => ...` (extra creativity to add a verb here?) 4. The action creator's return struct: `... => ({ type: ACTION_NAME, payload: arg })` 5. The reducer switch clause `case ACTION N…

It's just javascript... when I'm writing a redux-backed app I will often abstract out commonly repeated patterns in action creators and reducers. Every project is different so I just wait until things start looking predictable and refactor. Not trying to be snarky, I just see this a lot at work; people seem to be locked in to the patterns used in the redux documentation and never attempt to rewrite it as they would a…

Actually, I agree with you and appreciate that redux doesn't force something like a framework on you. You have choice of (non-)immutability, async handling, organizing your code, or how to "wrap it up" like you suggest.
Post reply on HN