fgerschau / comments

1 stars 0 forks source link

react-rerender-components/ #3

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

When does React re-render components?

React re-rendering explained and how to optimize React's re-render performance

https://felixgerschau.com/react-rerender-components/

victor-magarlamov commented 3 years ago

Thank you for this article! This is the best explanation I have ever seen. You explain React rendering better than Dan A.)

fgerschau commented 3 years ago

Hey @victor-magarlamov, thanks for the nice words! Not sure though if I explain it better than Dan, but Iā€™m glad that you liked it šŸ˜„

escornwell commented 3 years ago

Very clear and helpful. I'll note that I get warnings when I use e.target.value unless I change it to e.currentTarget.value. The former access the native event property, while currentTarget is the synthetic event's property, as I understand it.

fgerschau commented 3 years ago

Hey @escornwell, thanks for pointing that out!

According to stack overflow, the difference lays in which element you're accessing.

Basically, events bubble by default so the difference between the two is: target is the element that triggered the event (e.g., the user clicked on) currentTarget is the element that the event listener is attached to.

papercoding22 commented 3 years ago

Thank @fgerschau, I googled and visited all the articles about this topic, but your article is the only one I stayed at the longest.

Mokkapps commented 3 years ago

Thanks for this article, well written and good technical details šŸ‘šŸ»

jack-lin-jql commented 3 years ago

Absolutely loved reading this! Thanks a ton <3

javedinfinite commented 3 years ago

Thank you for this article.

kautious80 commented 3 years ago

Thanks for the excellent explanation. One of the best articles I've read on this re-rendering

tochukwuali commented 3 years ago

Really enjoyed reading your explanation. It was insightful. Thank you.

Silidrone commented 2 years ago

Thank you for the article, it's an in-depth explanation on React rendering. There is one thing I find weird though, if for optimizing a React app, bringing your data as close to where it's used as possible (or as down in the Component hierarchy as possible) is needed, then how does Redux make sense? And also one of the most important rules "Lifting state up" in React logic. Because in React, usually it is preferable to lift the state up the Component hierarchy to allow for better React app design logic.

fgerschau commented 2 years ago

@Silidrone Redux follows the same principle by connecting the components that need the data (as close as possible). These components only re-render if the mapped props change.

Lifting state up still makes sense, despite the fact that it causes more re-renders.

Keep in mind that there's a difference between a React render and a DOM update. Generally, React renders are fast, and you shouldn't worry too much about it unless you are using expensive JavaScript functions in the render function. DOM updates, on the other hand, are what takes a lot of time and this is what React optimizes for.

So while it does make sense to be aware of re-renders, it doesn't make sense to try to avoid (React) re-renders at all cost because the performance impact will be minimal.

papercoding22 commented 2 years ago

Thank you for the article, it's an in-depth explanation on React rendering. There is one thing I find weird though, if for optimizing a React app, bringing your data as close to where it's used as possible (or as down in the Component hierarchy as possible) is needed, then how does Redux make sense? And also one of the most important rules "Lifting state up" in React logic. Because in React, usually it is preferable to lift the state up the Component hierarchy to allow for better React app design logic.

I just wanna add more comments along with @fgerschau, yes I heard this quote somewhere "Premature Optimization Is the Root of All Evil".

The trade-off when we bring Redux state as close to where it's used is it would become "tightly coupled" structure and make them impure while we are trying to avoid it. Plus when the state is injected deep down the tree, it will gradually become more difficult to maintain and fix bugs.

SunbeamRapier commented 2 years ago

I found this article interesting, and I had hoped it would solve a problem for me, but it didn't. I have a simple problem: I have a footer component which urges the user to view the component page where they can buy my book. But once they navigate to that component page I want to suppress the footer so I am not nagging them...

I have a state variable in the Book component. It initialises to 0 and increments by 1 each time the code for that component runs. If that count is > 1 then it should suppress the footer.

In the footer (I condition the div output by a variable which is either Yes or No. And perhaps it does, except that React appears to decide it doesn't need to re-render the footer so it remains turned on. I tried adding a state variable to the footer itself, but that just caused a zillion renders for some reason I don't understand.

it should be easy but React has a mind of its own and I either get the footer all the time, or never. No-one on any other forums has been able to solve this problem either. Of course, if there was an actual React Manual it might be easier to solve problems like this.

I am wondering whether I should abandon React altogether and switch to VueJS - where they do have a manual! I seem to spend all my time trying to figure out what React is doing, and trying to make it do what I want, and failing...

antonarbus commented 2 years ago

I tried to check the following statement and had not succeeded.

"... all its subsequent child components will re-render, regardless of whether their props have changed or not.."

Here is the jsfiddle where I have one parent and 2 children components and components alert on render.

Can somebody explain please?

fgerschau commented 2 years ago

@sherbsherb that's an interesting example. You are using composition at the outer level instead of rendering the children in the parent function.

The outermost component would be the following, which only renders once, since the state in here doesn't change.

const toRender = (
  <ParentComponent>
    <ChildComponent1 />
    <ChildComponent2 />
  </ParentComponent>
);

Try changing your code to render the children inside the parent, and you'll see that the children re-render on every update.

function ParentComponent(props) {
  const [parentState, setParentState] = React.useState(0);
  console.log("parent component triggered");

  return (
    <div>
      <button
        onClick={() => {
          setParentState(parentState + 1);
        }}
      >
        Change parentState
      </button>
      <ChildComponent1 />
      <ChildComponent2 />
    </div>
  );
}

The reasoning behind this is that React re-renders a component if its state changes, but it doesn't re-render the props if they don't change.

This article explains this more in detail. I'll try to update this article soon to explain this a bit better.

antonarbus commented 2 years ago

@fgerschau thank you very much!

Speckope commented 2 years ago

Very clear explanation, thanks!

oiver555 commented 2 years ago

If you put everything in the root component of your application, all the React.memo functions in the world won't help you to fix your performance problems. Hilarious!! Much confusion was cleared up in this write up of yours!

praveena-muk commented 2 years ago

Very clear and helpful article! Thanks Felix

huseyn commented 2 years ago

Hi, many thanks for this great article. But this part of article: Check out the optimized version of the example and type in some text- in here when I type something, nothing happen in both sides (no memo and memo)

fgerschau commented 2 years ago

@huseyn the optimized version is supposed to do nothing, as it optimizes the re-renders. I'm not sure, though, why the first example doesn't work for you. In the Chrome browser at least, it updates the re-render counters on every keystroke.

sumeet-sood27 commented 2 years ago

difference between virtual render and native rerender

sumeet-sood27 commented 2 years ago

While optimizing the example used in React.memo articles, you moved to state to its own component - InputSelfHandling. but what if we need that state in parent as well as other siblings of InputSelfHandling? you said "If you need to use the state in other parts of your application, you can do so by using React Context or alternatives like MobX and Redux", if we use react context, then also changing that value will cause the rerender of all components which use context. so how does this optimize?

fgerschau commented 2 years ago

@sumeet-sood27 good point. MobX already does this optimization for you, I believe, but you're right regarding React context. For that, you'd need to wrap the state in useMemo to avoid re-renders.

But sometimes you can get around that. Say you have an input with a button. You can pass the value to the parent and siblings by calling a callback that is passed down as a prop; this way the state only updates once instead of on every keystroke.

If you're aware of the different ways to optimize, you can pick the one that most suits the situation. Just don't start with memoizing everything šŸ˜„

difference between virtual render and native rerender

A native re-render is when the browser re-paints a part of the DOM, which is quite expensive/ slow.

A virtual re-render is the execution of the function component, after which React decides whether the browser DOM needs to be updated or not. React does this by using a virtual DOM to see if anything changed.

sumeet-sood27 commented 2 years ago

HI, a)you said Mobx optimizes it, what about redux? Also cuple f questions form last comment - b)what do you mean by "wrap the state in useMemo"

sumeet-sood27 commented 2 years ago

You said - "But sometimes you can get around that. Say you have an input with a button. You can pass the value to the parent and siblings by calling a callback that is passed down as a prop; this way the state only updates once instead of on every keystroke."

it means to child component , I can pass a prop which is function. now this function calls the state setting function(state is maintained in parent). now I need to call this state function which is prop when user moves away form input.that way in parent component state will change only once.

this could have been done with passing the prop, instead of chnaging the state on every keystroke, we should change state on blur event

itpsolver commented 1 year ago

Thank you. This article was very helpful to me

tiennsloit commented 1 year ago

Re-rendering between parent and children components is a big headache for me. I figured out using Redux to solve the issues without a good explanation. Your article gathers everything about re-rendering in one place and help me a lot. Thanks.

mathpaquette commented 1 year ago

good job !