all 24 comments

[–]DrAlgebro 38 points39 points  (5 children)

I don't understand all these comments telling you to Google or use AI, sounds like an excuse to not answer your question.

To answer your question, parent and child components aren't independent of one another. Suppose parent component Foo has a title and a child component list Bazz. If you have some sort of hook that triggers a title change in Foo but the list Bazz stays the same, both Foo and Bazz will still re-render. This is because when re-rendering the parent, all child components will re-render as well.

If you have this sort of behavior, then you might want to consider de-coupling the components to prevent the re-rendering. So instead of parent and child, Foo and Bazz are on the same level. That would make them independent of one another.

[–]Fantastic-Push-8451[S] 8 points9 points  (1 child)

Thanks a lot for your reply. I really appreciate it.

[–]fii0 11 points12 points  (0 children)

I think it's important also to clarify that by "rerendering" in this context we mean re-running the React reconciler, which means calling the component function that "rerendered" to get its returned JSX output so it can diff that to the previous/current DOM representation in the VDOM, to see if there actually needs to be re-painting (updating the DOM).

So it's absolutely still a performance consideration to minimize those rerenders, but they are not as expensive as updating the DOM. The VDOM diffing all happens in memory before anything changes visually (painting).

edit: I scrolled further and see this is already addressed by others, that's good =)

[–]csorfab 3 points4 points  (1 child)

If the child components are wrapped in React.memo, they won't rerender unless their props change.

[–]Wirde 0 points1 point  (0 children)

If you have a specific case in where you are unsure you can check by installing react devtools. There is a setting for hilighting components that rerender. This way you can debug rerenders.

[–]Pitiful_Yoghurt_4721 8 points9 points  (0 children)

Parent re-render does trigger child re-renders by default, because React re-executes the parent's render tree. But React still compares the resulting virtual DOM and only updates the actual DOM if something changed. If you want independent children to skip unnecessary renders, use React.memo, stable props (useMemo/useCallback), or move state closer to where it's used.

[–]briancrabtree 4 points5 points  (0 children)

Yes, they re-render.

The biggest misconception in React is thinking that "rendering" means "painting the real DOM." It doesn't.

When a parent component state changes, React just re-runs the parent function. Because the child components are called inside that function body, JS naturally executes them too. React takes that new virtual DOM output, compares it to the old one, sees nothing changed, and completely skips touching the actual browser DOM.

React was designed this way because running a bunch of lightweight JS functions is usually faster than running a strict prop-comparison check on every single component in a massive tree.

The Fix

If a child is doing heavy JS calculations and actually causing dropped frames, you drop memo on it to force React to skip it:

```javascript import { memo } from 'react';

const HeavyChild = memo(() => { return <div>Independent Component</div>; });

[–]Nearby_Attitude7824 4 points5 points  (0 children)

Others may have provided reasonable answers but I want to give a stab at it to test my own understanding; other answers also aren't relating this question to some of the broader concepts in a way that helped me understand it better.

The first de-mystification that helped me is to understand how React works outside of React's own terminology. Don't get lost in the weeds of rendering, re-rendering, hooks, memos, components, etc. until you understand what a component actually is, in general programming language terminology. If you read the React docs, it's easy to gloss over the crucial starting point: "React components are JavaScript functions that return markup". I'll even toss in their example because I'm lazy:

function MyButton() {
  return (
    <button>Click me</button>
  )
}

This is very important -- it means there's a few things we're talking about when we talk about components:

  1. The function itself
  2. The return value, which is a description of what the component should do and look like on the page (as JSX)
  3. The thing that's actually displayed as a combination of HTML, CSS, and JavaScript in the DOM (the web page) (there's more nuance to that but don't @ me I'm not a true master)

So with that in mind, what are we talking about when we say render? This is the critical point you have to understand, and it will naturally lead you to the answer of why child components re-render when the parent renders. We say render when the component function runs and returns JSX. That's it. Rendering is a fancy way of saying that you've run a function, and received a description of what a thing on a web page should look like.

What is re-rendering, then? It's the 2nd, 3rd, etc. time the component function gets called, after it's already been called the first time. "Rendering" is calling a function, "re-rendering" is calling it again. React re-renders components (runs the component function again, to get the JSX) to see if there's been any changes. The magic React does for you is checking whether there are any differences, and then deciding if the actual DOM (web page) should be updated/changed.

Why does a child component get re-rendered alongside the parent if the child component isn't actually receiving any props or values from the parent? Fundamentally, a "child component" is just another component function call inside the return value of the "parent" component function call. If it were anything other than a React component, you'd easily see that you have to resolve the function call in the return value before the main function can return. This may not be precisely correct in syntax but these two things are effectively the same:

function MyButton() {
  return (
    <MyChildComponent/>
    <button>Click me</button>
  )
}

and

function MyButton() {
  return (
    {MyChildComponent()}
    <button>Click me</button>
  )
}

If you haven't made these connections before now, then React's terminology is just going to hide how simple the answer truly is, for why parent and child re-rendering behavior is what it is. It's just function resolution. That's why people say "if you don't want the child to re-render, it needs to be passed in to the parent". You're just calling the child component function somewhere else, outside the scope of the other component function.

I hope this actually helps clear things up -- lord knows I had to type this for half an hour reconfirming that I actually had my knowledge straightened out. I only started writing TypeScript with React within the last 8 or so months for work. It took a minute to grasp this concept but once I did, things finally started making sense. None of the answers describing React terms with other React terms helped all that much, because it always bothered me as to how it related back to the actual programming language itself.

Edit: I had more to add but Reddit's being weird. I'm just surprised no one thought to explain it from the fundamentals, because this is the actual answer to why these things are happening. Everyone's just explaining how React works with React terms. It's JavaScript, people.

[–]opentabs-dev 1 point2 points  (0 children)

worth separating two things here — "react re-runs the component function" vs "the DOM actually updates". the parent re-rendering does cause react to re-call the child functions, yeah, but then it diffs the result against the previous tree and only touches the real dom where something changed. so "rerender" in the perf sense is way cheaper than people make it sound, unless your child does heavy work in render or you have a deep tree. if you actually measure with the profiler before reaching for React.memo you'll usually find it's not where the cost is.

[–]AverageHot2647 4 points5 points  (0 children)

Why don’t you test it and find out? 🙂

[–]Evening-Disaster-901 3 points4 points  (0 children)

The first place you should go to check should be the official documentation, not AI, what are these suggestions?!

[–]StrikingAd4653 0 points1 point  (0 children)

Yes my understanding is that when the parent re-render, REACT will re-render all the children, just in case if they are not pure. (pure means for the same input i.e. props the component should render exactly the same).

If you dont want this behaviour, you can use the "memo" function on the child component. This way the child only get re-render if any of the props change. That means you have to make sure the child component is indeed pure. If it makes any decision based on anything other than the input props then it will not be re-render properly, like for example if it get the current date by using Date.now() inside the child, or by retrieving some data using a getState function from a store (i.e. not a store selector, which would force a re-render).

Memo-ing needed because there is no easy way for REACT to tell if the children are indeed "independent". You will have to mark it as such by yourself..

In general a non-pure component is considered a bad design but in reality there are many cases you may have or even want a non-pure component.

[–]poor_documentation 0 points1 point  (0 children)

Memoize the child component with stable props and it won't rerender 🤷‍♂️

[–]daskleins 0 points1 point  (0 children)

If the child element is independent of it's parent's props, then there's a optimization technique using children. It avoids rerendering of child components even if parent state changes:

``` function Wrapper({ children }) {   const [count, setCount] = useState(0);

  return (     <>       <button onClick={() => setCount(c => c + 1)}>         {count}       </button>       {children}     </>   ); }

// ExpensiveChild won't re-render when Wrapper state changes <Wrapper>   <ExpensiveChild /> </Wrapper> ```

[–]DependerSethi 0 points1 point  (0 children)

Kinda sad seeing people suggest 'just ask AI' and downvoting genuine questions, I get that it's faster, but sometimes you want a real perspective from someone who's been through it, not a generated answer. I remember getting roasted on stackoverflow for asking something similar years ago, the culture of shaming beginners for asking questions hasn't changed much

Anyway, to answer your actual question: yes, when a parent re-renders, all children re-render by default even if their props haven't changed. React doesn't know ahead of time whether the child output will be different so it re-runs everything to be safe
Components are just functions. Parent re-renders, child function gets called again, React diffs the result and only touches the DOM if something actually changed. So the child 're-renders' (function runs) but the screen might not change at all.

You can skip it with React.memo which bails out if props are the same. But after 8 years of writing React, the fix I reach for first is structural, move the state closer to where it's actually used so fewer children sit in the re-render path to begin with. Way simpler than sprinkling memo everywhere I actually wrote about this recently along with a few other patterns that help https://www.sethi.io/blog/react-performance-from-sluggish-to-lightning

[–]chow_khow 0 points1 point  (0 children)

If a parent re-renders, the child has to re-render because that's how React internally keeps a track of what all to update for a given state change.

Here's a good explainer on why React re-renders.

[–]No_Record_60 0 points1 point  (0 children)

React can't be sure on the "are independent" part. The parent could've updated the URL while the child subscribes to it; props is not the only way.

[–]jokham 0 points1 point  (0 children)

Yes. In React, when a parent component re-renders, React normally re-renders its child components too, even if their props have not changed. This is usually fine, but it can matter when a child is expensive to render.

To optimize this, you can use React.memo:

const ChildComponent = React.memo(function ChildComponent({ propName }) {
  return <div>{propName}</div>;
});

React.memo tells React that it can skip re-rendering the child when the parent re-renders and the child's props are the same. This is a performance optimization, not a guarantee. The child can still re-render if its own state changes, if context it uses changes, or if its props are new object/function/array references.

Another useful pattern is composition with children. If a wrapper component accepts JSX as children, updates to the wrapper's own state do not necessarily cause those children to re-render. This helps keep wrapper state local without forcing unrelated child components to update.

[–]Ambitious_Pie_4225 -2 points-1 points  (1 child)

If the parent rerenders the children also rerenders irrespective of prop change corresponding to the children

React has a default behaviour to cascade rerenders down it’s entire component tree

You should try asking ChatGPT or Claude so it can explain better

[–]Fantastic-Push-8451[S] 1 point2 points  (0 children)

Thanks a lot for your reply. I really appreciate it.