Hacker News new | ask | show | jobs
by phryneas 1925 days ago
That does not sound like you are up-to-date with what the official redux tutorials currently recommend for writing modern redux. https://redux.js.org/tutorials/fundamentals/part-8-modern-re...

Also, two-way-data-bindings like just `state.totals` work when you're just re-rendering your whole app on every frame, but as soon as you get away from that, there will always be either some "observing" or "signalling" involved to trigger rerendering of the correct parts of your application. Redux goes the "signalling" way, MobX goes the "observing" way, both have their benefits and drawbacks.

2 comments

> That does not sound like you are up-to-date with what the official redux tutorials currently recommend for writing modern redux. https://redux.js.org/tutorials/fundamentals/part-8-modern-re...

--- start quote ---

import { combineReducers } from 'redux'

import { createStore, applyMiddleware } from 'redux'

import thunkMiddleware from 'redux-thunk'

const composedEnhancer = composeWithDevTools(applyMiddleware(thunkMiddleware))

import { createSlice } from '@reduxjs/toolkit'

...createSlice will automatically generate action creators

--- end quote ---

It's.... it's not better in any way?

> Redux goes the "signalling" way, MobX goes the "observing" way, both have their benefits and drawbacks.

I like Svelte's approach. Where they figure out which things are being observed or changed at compilation/transpilation time and generate code for that case specifically.

That page introduces one tool after another, replacing all those external tools with the officially recommended Redux Toolkit that wires all of them up for you.

In the end you are left with only

`import { configureStore, createSlice } from '@reduxjs/toolkit'`

> That page introduces one tool after another, replacing all those external tools with the officially recommended Redux Toolkit

Perhaps. As person who's never used thunks or, really, half of those tools in conjunction with Redux, this tutorial is quite confusing.

> In the end you are left with only import { configureStore, createSlice } from '@reduxjs/toolkit'

The final code on the page is literally

  import {
    createSlice,
    createSelector,
    createAsyncThunk,
    createEntityAdapter
  } from '@reduxjs/toolkit'

The page doesn't really address the issue of verbosity and the flow as described in the original comment. It just hides some of it behind some facades with autogenerated accessor functions (so, even more levels of abstractions).
Yes, the entire point of that page is:

- You've gone through this whole tutorial sequence and should now understand how to write all this Redux logic "by hand" and why these standard Redux usage patterns exist

- Now, here's how Redux Toolkit abstracts and simplifies those exact same patterns, so that you can do the same thing with less code, but you understand what those abstractions are doing for you internally.

What's one good reason why JS proxies (which let you listen to "state.totals = 100") aren't a cleaner solution to trigger a rerender?

There's no need to rerender the whole frame - will be happy to provide an example on request.

That would be the "observing" approach I described.

The upside of an action-based (signalling) approach is that you have a better time separating concerns as actions (if used correctly) represent intent, so your component emits an event and the state acts accordingly, removing state logic from your representational components. Might also be a lot easier to see in the DevTools what happened when and why.

Of course not every app needs a pattern like that, that's why I said both approaches are valid.

My point is that the action-based approach you describe is extremely verbose for very little gain. Most apps don't need it, yet that's what Redux forces you to do.

Regarding DevTools, it's just as easy to make it work with "observing".

Also, I'm not saying you should write state changes and data fetching in the UI components. By all means write them under actions/services whatever. I'm complaining about the complexity around effecting that change.

It doesn't seem verbose to me. Have you looked into those docs above? You define a reducer and an action creator is automatically generated. String action types are an implementation detail. No manual immutable state modification, as immer is baked in. Modern redux is maybe 20% of what you might be imagining if you only know legacy redux.

It's not much more code than writing a function, but other reducers of your state can suddenly act upon the same action, you can trigger side effects using middleware and of course watch stuff "by intent" and not "there was a modification" in the devtools. All while keeping everything separated pretty well.