DEV Community

Discussion on: Get to know Redux in 2021

Collapse
webduvet profile image
webduvet • Edited on

I think redux-toolkit is just plain ugly. The only nice part is that integrates with react hooks. It is just too little for platform "independent" library.
it states solving 3 problems:

1.  "Configuring a Redux store is too complicated"
2.  "I have to add a lot of packages to get Redux to do anything useful"
3.  "Redux requires too much boilerplate code"
Enter fullscreen mode Exit fullscreen mode

And I don't thing they were problems at first place and even if they were (for some) it does not solve it.

  1. not it is not complicated at all. It's rather plain simple. toolkit is IMO more comlicated as it tries hiding things.
  2. no, redux is the only required package and if you work with react there one more - react-redux. anything else is just app developer decision.
  3. no, it does not. it's about the same as with toolkit.
Collapse
markerikson profile image
Mark Erikson

You've complained in multiple threads that RTK is "ugly". What, specifically, do you think is "ugly" about it?

Also, RTK does solve all three of those issues:

  • Creating a Redux store with correct defaults is now a single function call with one required argument, instead of 30-40 lines with a bunch of conditional logic to set up applyMiddleware, check for window.__DEVTOOLS_EXTENSION__, compose() them together, etc.
  • RTK depends on the standard Redux packages like redux-thunk, immer, and reselect, so you only have to add @reduxjs/toolkit yourself.
  • It does eliminate all the boilerplate code. No more nested spread operators, no writing action types or action creators by hand, and APIs like createAsyncThunk and createEntityAdapter for simplifying standard use cases.

If you don't like Immer's "magic", that's a valid opinion and up to you. But as the primary Redux maintainer, I've seen all the problems and pain points people have had with Redux over the years. RTK does solve those problems, and the huge amount of positive feedback we've gotten about RTK reflects that.

Collapse
webduvet profile image
webduvet

It's my right to complain :) BTW thumbs up for the good work. I think redux was bulls eye and it changed FE application development forever. However I have my opinions about opinionated toolset.

  • if you have 30-40 lines to setup your store then you probably require something more than default automatic configuration. Besides that, It is not something I do every day or every week. not even every month. And I always can just copy that from previous project. I have full overview and control and I like to keep thinks simple.
  • so if I use toolkit as opposed to plain redux I have redux-thunk, immer, reselect and redux-toolkit in my dependency list. I find immer on verge of hating. to me it is not readable enough. I usually use plain js or ramda. Immer just hides things assuming that is what people want. Helping by hiding is not great approach.
  • again I would happily trade few extra key strokes any day in exchange for better readability and better control.

If I compare my reducers and selectors against something written using redux-toolkit I fail to see any excessive what you call boilerplate code.

Examples of things I do not like:

I do not like action creators coupled with reducer. It is just a function and You could hardly find anything simpler than that. redux-toolkit takes that simplicity away.
Why do you see the need for a factory method for a function?

I do not like the createAsyndThunk. redux-thunk is by definition async. I believe that catering for developers who do not
understand 7 lines of code (redux-thunk) by creating convoluted API for redux-thunk is just too much.

Thread Thread
markerikson profile image
Mark Erikson

Agreed that store setup is typically a once-per-project kind of thing. But, it's something you have to do for every project, and being able to do that in one function call, and get correct defaults out of the box (including dev mode checks that catch common errors) is a big improvement.

I'm really not understanding what you don't like about Immer. For comparison:

// hand-written immutable update
function handwrittenReducer(state, action) {
  return {
    ...state,
    first: {
      ...state.first,
      second: {
        ...state.first.second,
        [action.someId]: {
          ...state.first.second[action.someId],
          fourth: action.someValue
        }
      }
    }
  }
}

// one-liner with Immer
function reducerWithImmer(state, action) {
  state.first.second[action.someId].fourth = action.someValue
}
Enter fullscreen mode Exit fullscreen mode

Writing reducers with Immer results in much less code, and much clearer intent as to how you're actually trying to update state. Also, hand-written immutable updates are very prone to errors, and accidental mutations have always been the #1 cause of bugs with Redux. Immer eliminates those completely.

So, between making the code shorter and easier to read, and eliminating accidental mutations, Immer is a huge improvement for Redux users.

We have always encouraged the user of action creators as a standard practice with Redux, and I wrote a separate post on "why use action creators?" several years ago. They provide a consistent interface for dispatching actions, and also encapsulate any logic needed to set up the action object (such as generating unique IDs or formatting parameters). With RTK, you get them for free anyway, so there's no reason not to use them.

redux-thunk is by definition async.

This is incorrect. A thunk may contain any logic, sync or async, and you can still write them by hand. However, we have always encouraged the "dispatch pending/fulfilled/rejected actions" pattern, and that requires additional work: defining the action types and action creators for all three cases, and writing the logic to dispatch those actions at the right times with the right contents. So, it's a lot more than "7 lines" for each thunk if you're writing all those action creators and action types by hand. createAsyncThunk does all that for you.

Thread Thread
webduvet profile image
webduvet • Edited on

1.) purposfully written example. It is rather unusual to have action targeting four levels. You could run into few worse problems than verbose code. like change in API contract if that is what defines the shape of your state object.
But if I had to I would use my favourit little functional library and it would look e.g. like this

...
return mergeDeepRight(state, { first: { second: { [action.payload.someId]: { fourth: 'hello from here'} }}})
Enter fullscreen mode Exit fullscreen mode

as opposed to:

function reducerWithImmer(state, action) {
  state.first.second[action.someId].fourth = action.someValue
}
Enter fullscreen mode Exit fullscreen mode

the beauty of the first version is that it returns the new state object. your example does not return anything and relies on immer's internal magic to figure it out
That impacts your tests and the general readability of your code.

2.) redux-thunk - what I mean by definition - perhaps wrong wording - you define the function which is executed in the middleware and returned. whether the function is async should be of no concern to redux or toolkit
so if you define function which returns promise then you know what you are doing. I can't see how is this difficult. Why does this justify a wrapper which is 50 times bigger than redux-thunk itself?

defining the action types and action creators for all three cases, and writing the logic to dispatch those actions at the right times with the right contents. So, it's a lot more than "7 lines" for each thunk

I meant redux-thunk logic is in 7 lines. however dispatching right actions with right content at the right time - you still need to take care of that whether you use redux-thunk, toolkit or your own middleware.
I only can speak for myself when I say I've never seen the above mentioned three problems which toolkit is trying to address as problems at the first place. It is maybe be because I've been already addressing them unconsciously similar way as I address similar problems outside react-redux world. But for me and like minded developers it might feel like toolkit is being forced down the thought by statements like

The Redux Toolkit package is intended to be the standard way to write Redux logic.

Thread Thread
markerikson profile image
Mark Erikson • Edited on

FWIW, I can tell you I have seen all of these problems pop up, thousands of times over the years. I wouldn't have created RTK if these problems didn't exist. (and that includes seeing some very deeply nested immutable update logic - that example is fictional, but I've seen multiple cases at least that long in real production code.)

And yes, we are telling people that RTK is the right way to use Redux at this point, because it solves all of these problems, and the highly positive feedback we've gotten reflects that.

Just a couple days ago I got this DM:

Hello! I'm a software engineer who's been using Redux almost exclusively for state management for a few years now, and I wanted to say that Redux Toolkit is amazing. I've tried a few other ways to manage state, but I just love the principles behind Redux and kept coming back to it. The one thing I couldn't stand was the boilerplate at first, and I actually tried creating my own utilities to simplify it as much as possible. A couple years ago, I found immer and made my own "reducer producer" that used immer to make immutable reducers while writing simpler mutative code. Soon after, I found Redux Toolkit's createReducer which had practically the exact same API as my own and was so happy. More recently, I have been using my own utility called "geese", where I: 1. Define a "goose" (playing off of the "ducks" pattern) with an action name, creator, and handler (reducer) 2. Combine them into a map typed as "geese" 3. Create the reducer and action map from the geese using a utility function After a bit more simplification, I arrived at a final API and was in the middle of implementing it... When I found "createSlice" and realized it's practically identical. In short, I just wanted to say that Redux Toolkit is amazing and basically works exactly the way I would expect an ideal boilerplate-reducing Redux utility to work.

Some other similar responses:

1)

it’s hard to overstate how much I’m enjoying getting to migrate things to RTK. The patterns it uses / encourages just make things to much easier. Have been working on migration PRs to show our devs how to do it and it’s already made me bummed to look at the old code.

2)

BTW, we just switched from context and hooks over to RTK on one of our production application's frontends. That thing processes a little over $1B/year. Fantastic stuff in the toolkit. The RTK is the polish that helped me convince the rest of the teams to buy into the refactor. I also did a boilerplate analysis for that refactor and it's actually LESS boilerplate to use the RTK than it is to use KCD's recommended dispatch pattern in contexts. Not to mention how much easier it is to process data.

3)

I'm a huge fan of how effortless it is to create airtight typed Redux setups now with Redux Toolkit. Extremely appreciative of the incredible work you and the rest of the good folks working on Redux have given the community.

I'm not saying that you personally must like RTK or use it. I am saying that it does solve the problems that most Redux users have experienced, and that almost everyone who has used RTK loves it.

Thread Thread
webduvet profile image
webduvet

Well, I'm not arguing that many find it easier with redux-toolkit. You(as toulkit devs) obviously have vision and aim which is great. And you have a feedback from thousands of users and if this is how the community wants to drive it so be it. :)
I only expressed my own experience and my own opinion. Thanks for the discussion anyway, All the best!

Collapse
semirteskeredzic profile image
Semir Teskeredzic Author

Agreed, it does tend to use more "magic" approach, I can't see anything wrong or more complex if one wants to use Redux without toolkit package. Thanks for the insight.

Collapse
abror1997 profile image
Abror Xalilov

Agreed