Redux Toolkit == MobX?
Tags: redux, react, mobx, javascript
Published: 2020-05-25 19:00:07

I don't like Redux because of its complexity and dozens of lines of boilerplate code. So, I've never used it in production. When I worked on existing Redux-projects that someone left to me (you know, these aren't perfect projects 🤪), I always replaced Redux with MobX, and the code became clearer at times.

But today I tried [Redux Toolkit](https://redux-toolkit.js.org), an official toolset for efficient Redux development, and now I want to try it in production. In this post, I'm going to compare MobX and Redux Toolkit in terms of their simplicity. I'm not a Redux-guy, so feel free to point out my mistakes, if any.

Ok, here we go!

I won't show you a gradual transition from "Vanilla Redux" to Redux Toolkit, because you can find it in the docs. I just show you a simple "slice" (the equivalent of MobX store) with a counter.

```jsx
export const counterSilce = createSlice({
  name: 'counter',
  initialState: 0,

  reducers: {
    increment: (state) => state + 1,
    decrement: (state) => state - 1,
  },
})

export const store = configureStore({
  reducer: counterSilce.reducer,
})
```

You may ask, "What? Where is my ~~ugly~~ favorite action creators? Is it Redux?" At least I had just such questions a couple of hours ago.

*But how can you use it?*
It's simple, just like a regular store.

```jsx
const Component = () => {
  const dispatch = useDispatch()

  const counter = useSelector((counter) => counter)

  return (
    <section>
      <button onClick={() => dispatch(counterSilce.actions.decrement())}>
        -
      </button>

      <span>{counter}</span>

      <button onClick={() => dispatch(counterSilce.actions.increment())}>
        +
      </button>
    </section>
  )
}
```

And now look at the MobX store. Very similar, isn't it?

```jsx
// MobX store
export const counterStore = () => ({
  counter: 0,

  increment() {
    this.counter += 1
  },

  decrement() {
    this.counter -= 1
  },
})
```

### Fetching data

Now I'll show you a little more complex example: fetching data. I'll use [JSONPlaceholder](https://jsonplaceholder.typicode.com) API to fetch a list of users with Redux Toolkit.

Firstly, let me configure the slice. I'll store the `loading` flag and array of `users` in the state (error handling omitted for simplicity).

```jsx
export const usersSlice = createSlice({
  name: 'users',
  initialState: {
    loading: false,
    users: [],
  },

  reducers: {},
})
```

Here will be two reducers: one for setting `loading` to true (before fetching) and second for updating `users` (after fetching).

```jsx
export const usersSlice = createSlice({
	// ...

  reducers: {
    getUsersStart: (state) => ({ ...state, loading: true }),

    getUsersSuccess: (state, action) => ({
      ...state,
      loading: false,
      users: action.payload.users.map((u) => ({
        id: u.id,
        name: u.name,
        username: u.username,
      })),
    }),
  },
})
```

And I'll use an action creator which returns a function with `dispatch` for the request itself.

```jsx
const fetchUsers = () => (dispatch) => {/* ... */}
```

But wait, we need a `thunk` middleware for this, right? Indeed. But Redux Toolkit took care of that by [including some middleware by default](https://redux-toolkit.js.org/api/getDefaultMiddleware), so we don't need to install it manually.

The logic of the fetching function is simple: enable `loading`, make HTTP request, disable `loading`, update `users` array.

```jsx
export const fetchUsers = () => (dispatch) => {
  try {
		// enable 'loading'
    dispatch(usersSlice.actions.getUsersStart())

		// make HTTP request
    fetch('https://jsonplaceholder.typicode.com/users')
      .then((r) => r.json())
      .then((users) => {
				// disable 'loading', update 'users' array
        dispatch(usersSlice.actions.getUsersSuccess({ users }))
      })
  } catch (error) {
    console.error(error)
  }
}
```

And finally, we need to connect all this logic to React.

```jsx
const Component = () => {
  const dispatch = useDispatch()

  const usersStore = useSelector((store: Store) => store)

  useEffect(() => {
    dispatch(fetchUsers())
  }, [])

  return (
    <main>
      {usersStore.loading ? (
        <span>Loading...</span>
      ) : (
        usersStore.users.map((u) => (
          <div key={u.id}>
            <span>{u.name}</span>
            <span>{u.username}</span>
          </div>
        ))
      )}
    </main>
  )
}
```

You can find all these examples in my [GitHub repo](https://github.com/habdenscrimen/_redux-toolkit).

Yeah, Redux Toolkit is an amazing tool for Redux. Just try it and share your impressions.