Live data from Hacker News

Why React Re-Renders

joshwcomeau.com

81–90 of 168 posts

Re: Why React Re-Renders

#81
post #80

Earlier quoted context omitted.

FWIW, React has always been designed around some Functional Programming type principles, such as immutable updates. Immutable updates do in fact require that if you want to update `state.some.nested.field`, you have to make copies of _all_ objects in that path: `nested`, `some`, and `state`. This isn't unique to React. Yes, class component `this.setState()` lets you get away with mutations. That's not really a _good_…

When updating deeply-nested immutable objects, the Immer library is great. You call the `produce(immutableValue, draft => { ... })` function with some immutable value and a callback function that manipulates a mutable proxy object mimicking the immutable value, and then the function returns a new immutable value with the same changes made by the callback function. The mutable proxy object never escapes the callback,…

Yeah, we specifically built Redux Toolkit around Immer from the very first prototype that I wrote.

I had catalogued _dozens_ of immutable update libs between 2015-2018, and Immer is simply superior to all of them.

Which is why Immer is a non-negotiable part of RTK, and something we specifically tell everyone they should be using with Redux:

- https://redux.js.org/style-guide/#use-immer-for-writing-immu...

- https://redux-toolkit.js.org/usage/immer-reducers

(in fact, I recently got quoted on the top of the Immer docs with a tweet I wrote saying how awesome Immer is :) https://immerjs.github.io/immer/ )

Re: Why React Re-Renders

#82
post #57

Earlier quoted context omitted.

I love hooks, but I think they made a few mistakes. The weirdness around useEffect having different behavior with no second argument vs [] is one of them. And they should have included a useUnloadEffect() by default, even though it's trivial to write, just for clarity. It's way too easy to miscount the number of ()s in useEffect(() => () => {}, []); They also should have included a few other basic hooks, like useStab…

useRef is useStableValue

Not quite, having to use for current everywhere is just annoying, and it doesn't allow for a one-time constructor function.

Re: Why React Re-Renders

#83

I sometimes wonder what people are using React for, that they wouldn’t know this or have figured it out along the way. Let me kind of explain, as best I can, without code. We have a complex software product, an integrated compliance and risk management system with embedded workflow, automatic highlighting of potential risks due to non-compliance, plans of actions (aka risk management plans), RBAC, ABAC (used to contr…

> I sometimes wonder what people are using React for, that they wouldn’t know this or have figured it out along the way. The article is for beginners (the article itself says its intended audience beginner-intermediate, but I'd say it leans very much towards beginner). Thus this is precisely an example of how people who use React would learn this. It would be odd to comment on every explanation of a concept that ever…

Ah, OK, fair enough. For an article intended for beginners, well, it made think of those recipe sites that bury the details after autobiographical recollection.

It could have been ever so much shorter and clearer. But I’ve realized I really am becoming a get offa my lawn type as my 60s near.

Ah, Usenix and the early web, I miss thee. ;-)

Re: Why React Re-Renders

#84
post #80

Earlier quoted context omitted.

When updating deeply-nested immutable objects, the Immer library is great. You call the `produce(immutableValue, draft => { ... })` function with some immutable value and a callback function that manipulates a mutable proxy object mimicking the immutable value, and then the function returns a new immutable value with the same changes made by the callback function. The mutable proxy object never escapes the callback,…

Yeah, we specifically built Redux Toolkit around Immer from the very first prototype that I wrote. I had catalogued _dozens_ of immutable update libs between 2015-2018, and Immer is simply superior to all of them. Which is why Immer is a non-negotiable part of RTK, and something we specifically tell everyone they should be using with Redux: - https://redux.js.org/style-guide/#use-immer-for-writing-immu... - https://r…

Where will the Record & Tuple proposal (Stage: 2) fit in?

https://tc39.es/proposal-record-tuple/tutorial/

Re: Why React Re-Renders

#85
post #36

I sometimes wonder what people are using React for, that they wouldn’t know this or have figured it out along the way. Let me kind of explain, as best I can, without code. We have a complex software product, an integrated compliance and risk management system with embedded workflow, automatic highlighting of potential risks due to non-compliance, plans of actions (aka risk management plans), RBAC, ABAC (used to contr…

Sound pretty interesting! We’ve also implemented a DSL on top of React, see Lowdefy [0] We’ve taken a different approach, we’ve written a pure js engine which computes and manages state based on operator used to express logic, and then have a recursive render loop in react which provives engine with update hooks to it uses to rerender components when it should. That way we can very handle complex state logic and then…

I like the sounds of that. Every now and again we look at alternatives to our implementation: it works, so we don’t want to break it, but hic sunt draconis and caveat programmator.

I’ll be checking out that repo, thanks!

Re: Why React Re-Renders

#86
post #56

A pain point with React is large data structures. To re-render (assuming class components), you can setState with the changed property. For example if your state has two properties named foo and bar, and bar has changed then you call setState({ bar: newValue }). This works if you have simple properties. What if you have large complex data structures, and you need to modify a property deep down inside? Then you can ma…

> But it is tremendously wasteful to make a complete copy of a large data structure! You don't make a complete copy: you make a shallow copy of the spine, and then only descend along the fields you actually modify. The number of operations scales as O(branching factor * depth), not O(size).

I decided that this was what I would do on my most recent work project. My quest to reduce the number of libraries it depends on led me to deciding against Immer or something like it.

It works out cause I only use state of this complexity in a single spot. The code to do the copying does not read well in my opinion, and it definitely could get nasty in some cases (slower systems with updates on each keystroke say).

A library like Immer seems very reasonable if you are working on big nested structures often. Worth considering depending on the case.

Re: Why React Re-Renders

#87

I sometimes wonder what people are using React for, that they wouldn’t know this or have figured it out along the way. Let me kind of explain, as best I can, without code. We have a complex software product, an integrated compliance and risk management system with embedded workflow, automatic highlighting of potential risks due to non-compliance, plans of actions (aka risk management plans), RBAC, ABAC (used to contr…

You can get away with a lack of understanding about these things and still create beautiful products. For an example just look at Josh’s website. Beautiful react and design execution without knowing these details about rerendering.

Fair point. Speaks to the utility and power of React.

Re: Why React Re-Renders

#88

Josh's content is always very very high quality. I look forward to him releasing his online React course [0] so that I can recommend it to others who are starting out. My personal biggest not-total-comprehension is around Hooks / effects. I've followed tutorials, used them in production, etc. I'm comfortable using them but I also consider them a bit of a black box, which I don't like (e.g. I'm not sure how they're im…

They are yet more evidence that any human engineered system will inevitably 'diverge' to become the most complicated thing that just about works - what we might call the complexity horizon.

Driven by the power of our 'ingenuity', even the most elegant constructions will find themselves drifting towards this horizon. It takes super human effort to resist the effect, and super humans to keep systems from escaping us.

Re: Why React Re-Renders

#89
post #82

Earlier quoted context omitted.

useRef is useStableValue

Not quite, having to use for current everywhere is just annoying, and it doesn't allow for a one-time constructor function.

Why do you have to use current everywhere? You can do const { current: myStableValue } = useRef(computation);

Not sure what you mean by one time constructor function, but you can pass the result of a function to initial value.

const { current: myStableValue } = useRef((() => { //called once })());

Re: Why React Re-Renders

#90
post #56

A pain point with React is large data structures. To re-render (assuming class components), you can setState with the changed property. For example if your state has two properties named foo and bar, and bar has changed then you call setState({ bar: newValue }). This works if you have simple properties. What if you have large complex data structures, and you need to modify a property deep down inside? Then you can ma…

FWIW, React has always been designed around some Functional Programming type principles, such as immutable updates. Immutable updates do in fact require that if you want to update `state.some.nested.field`, you have to make copies of _all_ objects in that path: `nested`, `some`, and `state`. This isn't unique to React. Yes, class component `this.setState()` lets you get away with mutations. That's not really a _good_…

> React has always been designed around some Functional Programming type principles, such as immutable updates

If you think React has anything to do with Functional Programming, please read this ASAP: https://mckoder.medium.com/why-react-is-not-functional-b1ed1...

Post reply on HN