top | item 23102639

A Critique of React Hooks Addendum

73 points| vicarrion | 5 years ago |dillonshook.com

50 comments

order

karatestomp|5 years ago

Maybe a good place to ask this:

I've been hearing a lot of "oh we don't use Redux, we use hooks" lately, as if this obviously makes sense.

Am I missing something? To me this seems like "oh we don't use Redux, we use arrays". I'm gonna need quite a few more details before I can make any sense of a statement like that.

Like... what? How... how does that explain what you're doing? One of these things is not like the other. "Oh we don't use doors on our buildings anymore, we've switched entirely over to trees". Huh? What the actual hell does that mean?

acemarke|5 years ago

Hi, I"m a Redux maintainer.

Context and hooks don't "replace Redux", but they do overlap with some of the scenarios and use cases that previously led people to choose Redux.

Please see my post "Redux - Not Dead Yet!" [0] for information on how Redux compares to tools like React context + hooks and GraphQL, as well as situations in which it makes sense to use Redux.

I'd also suggest reading my post "React, Redux, and Context Behavior" [1] and watching my Reactathon 2019 talk on "The State of Redux" [2] for additional information on these topics.

As you noted, "hooks" and "Redux" are not exclusive. We released our React-Redux hooks API [3] last year, and it's been pretty enthusiastically adopted. We're now updating our docs to show using the hooks API as the default instead of `connect`.

[0] https://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet...

[1] https://blog.isquaredsoftware.com/2020/01/blogged-answers-re...

[2] https://blog.isquaredsoftware.com/2019/03/presentation-state...

[3] https://react-redux.js.org/api/hooks

ctidd|5 years ago

One of the problems Redux is used to solve (as a global store) is peace of mind that you won't need to refactor large swathes of component trees to reparent state and callbacks that need to be shared or persisted across different subtrees as new business requirements arise. Hooks (especially custom hooks, which are just a composition of other hooks packaged together as a single function) make the reparenting/hoisting/anchoring of state and callbacks trivial compared to other mechanisms, providing similar peace of mind that you're not boxing yourself into an inextensible component tree. (This is regardless of context; passing down props isn't a large pain point, and is often misguided to try to solve because it leads to importable components and hidden contracts.)

Render props and HoCs solve similar problems for composition/reuse of functionality (these are all mixins at heart), but the hoistability of hooks is really the distinguishing mark in my experience.

dceddia|5 years ago

The implication behind “we don’t use Redux, we use hooks” is that they’re using React’s Context API directly as a “store”. A component at the top level has some state, probably using the useReducer hook, that state is passed down using a Context Provider, and child components can access the data with useContext.

You can DIY a Redux imitation with hooks pretty easily but making it as performant as Redux is harder.

searchableguy|5 years ago

They might be using context. The problem with that though is it will cause performance issues due to unintentional rerendering. Not something to worry about for a small app.

https://reactjs.org/docs/context.html

ratww|5 years ago

If you ask a random sampling of Redux users why they're using it, you'll get tons of different answers. Some people use it as a caching layer. Other people use it because their SSR solution requires it. Other people use it because they like the action-command pattern. Other people just use it because they see it as the "M in MVC" and consider it mandatory in their projects. Other people just use it because it's the default. Some people use it for more than one reason.

If something else comes along and fits one of those niches, it's no wonder people will get interested in it. It was the same with Apollo. A lot of projects replaced Redux with it.

And to answer your question: some people are moving to hooks because of useReducer. Others because of useContext. Others because they can create custom Hooks. Some because of third-party hooks. Others for a mix of those.

wdb|5 years ago

Normally they mean they are using React Context, useReducer and React.memo/useMemo.

Most of the people saying that are using that are suggesting it lowers the code complexity as in the code is easier to understand or follow.

They probably will also split up the application state in multiple React context, one for auth, one for settings, things that aren't depending on one another.

Especially, when you are application doesn't have to manage that much state yet. I think it's a reasonable approach to get started with it. You can always switch to something like Mobx state trees or Redux at later time.

tildedave|5 years ago

I'd guess comments like this come from people thinking the primary complexity of Redux is the data store, rather than the "all changes to your state are represented as plain objects". The Redux FAQ goes into this: https://redux.js.org/faq/general#when-should-i-use-redux

Can't blame them missing the forest for the trees when you spend all your time writing the reducers and connectors vs the actions themselves.

speg|5 years ago

Perhaps they mean instead of Redux, they are using Context + useReducer.

davedx|5 years ago

I can give my take on this.

Until hooks I used redux in every app because it was the default way to manage state. Now I use hooks, I have more tools to help me manage state (and also load things via useEffect), I find I simply don't need redux anymore. The only compelling reason for me to pull in redux now would be if I wanted a centralised cache, but the kind of line of business apps I mostly work on lately just don't need to cache things like that, so each route/page just reloads the data from the server.

sjogress|5 years ago

We decided on the useReducer-hook instead of using a proper state library.

We did this since the thing we are currently building is essentially just a set of forms with a lot of client-side and server-side validations.

Of course, if we were building a large SPA we would probably reconcider at this point. It feels like we're already at the edge of what useReducer was designed to do and I do not think what we are doing now would scale cleanly to a larger project or a larger team.

pacomerh|5 years ago

saying "we use hooks" is a very broad term, a hook can do almost whatever you want. So I understand people that say that aren't being specific but it's assumed they're using a combination of hooks that would do a similar task like useContext, useReducer, etc

brlewis|5 years ago

I can't say for sure what they mean, but I'd guess it's saying they keep shared state in a parent component rather than having a global data store for their app. The useState hook might explain their chosen wording.

dcre|5 years ago

You are correct. The variety of replies makes that pretty clear if it was in doubt.

wnevets|5 years ago

[deleted]

stickfigure|5 years ago

I'm not quite sure what the point of this quiz is. I don't know the answer to those questions, and yet I seem to have no trouble building very large react applications (with hooks) anyway.

I would also struggle with similar quiz based on the callbacks for class components. And those I actually had to deal with on a frustratingly regular basis! At least with hooks I can remain blissfully ignorant of what happens under the covers of useEffect().

Maybe the answers don't matter and this is a pointless exercise.

acemarke|5 years ago

I'd definitely agree there's nuances about hook behavior that a lot of folks aren't familiar with. (Dan Abramov's mammoth post "A Complete Guide to `useEffect`" [0] ought to be required reading for all React devs, and a lot of the info in that post ought to be better integrated into the React docs directly.) That said:

- The "effect behavior runs bottom to top" has always been true about class lifecycle methods like `componentDidMount` / `componentDidUpdate`. So, nothing new there.

- Somewhat similarly, the aspect of new prop references causing some logic to run every time is not completely new, either - it's similar to how attempts to optimize rendering via use of `PureComponent`, `React.memo()`, and `shouldComponentUpdate` can "break" when the parent component passes down new callback or data object references every time.

- The complaint that "there's more stuff to learn" seems superfluous. If there was never anything new to learn, that would mean that the API was completely stagnant and that nothing new could ever be introduced. Yes, the ecosystem is in a somewhat uncomfortable transition state atm given that there's two different APIs that offer equivalent functionality, but "learning more stuff raises the barrier to entry" is not a particularly meaningful argument against hooks.

[0] https://overreacted.io/a-complete-guide-to-useeffect/

ng12|5 years ago

Agreed. At a certain point if experienced developers are struggling with the quiz it says a lot more about the quiz than the quiz-taker.

ng12|5 years ago

I thought the quiz was really missing the point. The whole point of reactive programming is to not worry about execution order.

hitekker|5 years ago

A clear, concise & clever blog post.

Quizzing the community on its supposed expertise, is such an effective way to separate rhetoric from reality.

wbobeirne|5 years ago

While I like the post and associated quiz, I feel like execution order is not the most important thing to understand with hooks, but it's the main theme of the quiz. If you're designing your components in an effective way, execution order shouldn't _really_ come into play. It typically only comes to bite you if you're manipulating some global state outside of React, or doing some direct DOM manipulation.

Questions 3 and 4 about anonymous objects and useRef are definitely the kind of knowledge that someone who aims to understand React and Hooks should focus on, though.

rdgthree|5 years ago

This was a great follow up. I completely agreed with the first post, and I couldn't help but think those critiquing it didn't quite understand what they were critiquing. It's rare that you're able to actually definitively prove that out, but these results are about as conclusive as it gets.