3 ms·
> separating the idea that "something happened" from "here's how the state updates in response" is key The idea is great, and has/had already been proven its v
by Jare 8y ago
> separating the idea that "something happened" from "here's how the state updates in response" is key
The idea is great, and has/had already been proven its value many times before. I love it, and I wanted to love redux for providing it to the masses. But every single experience I've had actually using redux (both my projects and other people's) had ended up with verbose, cumbersome and... messy code to read and analyze.
The ideal? I want to define a function with its parameters and that function performs the logic and data massaging it needs to. When I want that behaviour to trigger because something happened, I want to describe a call to that function with the right parameters with minimal scaffolding. Ideally, it would look exactly like I call that function, and the machinery that would turn that into posting an action that eventually reaches a reducer would be hidden from my sight. I do not want that scaffolding polluting my code. Defining string names for my functions? They are functions, they already have a name. Defining action objects to store the parameters? I already have a place for that, it's called "function parameters".
I don't know what sort of magic could provide this seamless integration of the reactive patterns into javascript, sort of some transpilation machinery. But I really, REALLY do not want it visible in my code.
- Jare 8y agoThat redux starter kit looks interesting and may alleviate many of my concerns. I don't know if it will eliminate them, but thanks a lot for that. [...edit...] Unfortunately, it looks brilliant with stuff like createSlice(), but it doesn't quite go far enough. If I have to deal with "action" and "payload" stuff then I am already polluting my code too much with stuff that I want to keep hidden in the machinery. My reducer functions should receive their actual parameters, not an "action" that they need to destructure into the actual parameters. And calling the actions in the slices should also wrap the store.dispatch() inside them. Ahhh feels so close to the ideal...
- acemarke 8y agoI'm not exactly clear on what you're looking for. Reducers, by definition, take two parameters: the current state and the action. They should return an updated state based on those two inputs only. The `payload` field is simply a common convention for consistently putting the "arguments" or "data" for that action type at a known key in the action each time. I'm also not sure what you mean by "calling actions should wrap `dispatch` inside of them".
- Jare 8y agoLook at the sample code in https://redux-starter-kit.js.org/api/createslice https://redux-starter-kit.js.org/api/createslice Since all actions contain just one parameter, it's easy to confuse things, so let's add a multiplyAdd function to multiply the counter by 'a' and then add 'b'. It would look like this: multiplyAdd: (state, action) => state * action.payload.a + action.payload.b I want it to look like: multiplyAdd: (state, a, b) => state * a + b or even multiplyAdd: (a, b) => this.state * a + b Because that is exactly the function/logic I want to describe. The 'action' and 'payload' are part of the scaffolding for redux execution flow. 'action' will contain data in it with the actual parameters, when javascript functions already support receiving parameters. I want the benefits of redux without paying for it in code clutter. There may be debate if this clutter is too much to pay or not, and that's fine. Plain redux imposes a lot more clutter and was still worth it for many people. My ideal is to reduce it to nothing. Now, the second part: store.dispatch(counter.actions.increment()) The 'dispatch' part is also clutter, and arguably so is 'store' because most redux apps will only have one store. So, I want that line to look like this: counter.actions.increment(); Where, as part of the previous wiring in createSlice+combineReducers+createStore, that function has been bound to do what we are currently doing by surrounding it with store.dispatch(). What's more, for our multiplyAdd function with two parameters, I (guess) we would be calling it as: store.dispatch(counter.actions.multiplyAdd({a:3,b:5})) And I want to call it: counter.actions.multiplyAdd(3, 5); For some it may be too much magic, but if you are in react-starter-kit territory I doubt it. For some it may be just me being pedantic and what the kit offers is already plenty, but the kit already moves away from plain redux and I just want to move it a bit further. Oh, and of course I want it all to work with types in Typescript. :) (I don't currently work with React or redux, so my ntoes are just a brain dump based on my past experience and expectations for future use, and certainly not a request, demand or criticism of redux or the kit).
- acemarke 8y agoWell, as I said earlier, the "function parameter" approach you're describing is just not how Redux works. You can only cause state updates by dispatching an action. An action is a plain JS object with a `type` field, and whatever additional fields you want. Your root reducer _must_ have a `(state, action) => newState` signature. Now, you can break up the internals of that reducer logic however you want, so I suppose in theory you could have some kind of "function parameters reducer factory" or something that extracts fields from the action, but that seems a bit silly to me (and it would also look really strange compared to all other Redux applications). As for the dispatching approach, most of the time you'll be dispatching these actions from a React component, in which case it's going to look like `this.props.doSomething()`. I will say that `createSlice` is currently limited in how it generates action creators. They currently only accept a single argument, which it turns into the `payload` field in the actions. If you're writing the action creators by hand, typically you could accept multiple function parameters in the action creator, and then combine those into a single `payload` object. The limitation is something of a tradeoff for not writing the action creators by hand. `redux-starter-kit`'s `createSlice` function was inspired by https://github.com/ericelliott/autodux https://github.com/ericelliott/autodux , which lets you optionally pass in some kind of a "payload creation callback" function. It would be reasonable to do something similar in our `createSlice`, but that's also more code you'd be writing by hand.