react icon indicating copy to clipboard operation
react copied to clipboard

Bug: React devtools "highlight updates when components render" and profiler output not matching when using memo

Open saranshkataria opened this issue 5 years ago • 14 comments

React version: N/A

Steps To Reproduce

  1. Create a dynamic list component
  2. Use memo to memoize the list, dynamically change one of the properties of an item on the list
  3. Open devtools and check the "highlight updates when components render" and "record why component rendered while profiling" option
  4. Start profiling and recording
  5. All components of the list are shown as being re-rendered
  6. Open React profiler and see the re-rendered items
  7. React profiler shows that only the selected item on the list was re-rendered

2020-09-05 13-23-43

Link to code example: https://codesandbox.io/s/practical-lovelace-ch4mw

The current behavior

React Devtools "highlight updates when components render" highlights all components. When using the profiler to do the same recording, it shows that only one component was re-rendering.

(My guess is that highlight updates is hooking into the function call itself and the profiler is looking into DOM changes and showing only those that actually re-render.)

The expected behavior

React Devtools "highlight updates when components render" should only show the components that were re-rendered

saranshkataria avatar Sep 05 '20 20:09 saranshkataria

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

stale[bot] avatar Dec 25 '20 13:12 stale[bot]

bump

saranshkataria avatar Dec 26 '20 20:12 saranshkataria

Maybe I don't understand how "highlight updates when components render" should work. It always highlights all components, doesn't matter they did render or not. I would think it should highlight only the ones that did render

Karolis92 avatar Jan 30 '21 17:01 Karolis92

Maybe I don't understand how "highlight updates when components render" should work. It always highlights all components, doesn't matter they did render or not. I would think it should highlight only the ones that did render

Even i force the child component not rerender through shouldComponentUpdate, it still highlight that child component due to its parents rerendered.

AlanCutFlim avatar Feb 20 '21 06:02 AlanCutFlim

My situation is the same as this issue.

I think it's occurred by Fragments.

I changed

Link to code example: https://codesandbox.io/s/practical-lovelace-ch4mw

like below and "highlight updates when components render" seems to work fine.

https://codesandbox.io/s/xenodochial-tharp-eq669

L56-71

  return (
-    <>
+    <div>
      <span>Images</span>
      {images.map((image, index) => {
        return (
          <ImageContainer
            key={image.title}
            image={image.image}
            title={image.title}
            handleSelect={handleSelect}
            selected={image.selected}
            index={index}
          />
        );
      })}
-   </>
+   </div>

yhor1e avatar Mar 18 '21 03:03 yhor1e

Here's a trivial example to demonstrate the issue (codesandbox):

import { memo, useState } from "react";

const BoringBtn = () => {
  const [click, setClicks] = useState(0);

  const act = () => {
    setClicks((cl) => cl + 1);
  };

  return (
    <div>
      <button onClick={act}>click me {click}</button>
    </div>
  );
};

const MemoBtn = memo(BoringBtn);

export default function App() {
  return (
    <div className="App">
      <div>
        This highlights: <BoringBtn />
      </div>
      <div>
        This doesn't: <MemoBtn />
      </div>
    </div>
  );
}

farcaller avatar Apr 14 '21 06:04 farcaller

I've encountered a similar issue with mobx. The highlight does not work for components wrapped by mobx observer. According to the explanation from the author of mobx here, it might relate to React.memo as well.

dpyzo0o avatar Apr 29 '21 10:04 dpyzo0o

I use to have this issue and now I have opposite... Memoized compoents are not market even tho they are re-rendered, because props changed.

Karolis92 avatar May 21 '21 17:05 Karolis92

My situation is the same as this issue.

I think it's occurred by Fragments.

I changed

Link to code example: https://codesandbox.io/s/practical-lovelace-ch4mw

like below and "highlight updates when components render" seems to work fine.

https://codesandbox.io/s/xenodochial-tharp-eq669

L56-71

  return (
-    <>
+    <div>
      <span>Images</span>
      {images.map((image, index) => {
        return (
          <ImageContainer
            key={image.title}
            image={image.image}
            title={image.title}
            handleSelect={handleSelect}
            selected={image.selected}
            index={index}
          />
        );
      })}
-   </>
+   </div>

This solved my issue. This is my view on this issue.React.Fragment converts all the children of the component as siblings of parent's other children. In fact, unknowingly, this violates the expected behavior that it must act as an independent component. Hence when the parent re-renders, it automatically re-renders all its children. React.Fragment somehow doesn't prevent re-rendering the unchanged component. Replacing it with a div makes the component have the usual behavior. Hence the highlighting of all the children in the component stops. It is also to be noted that it is not an issue with React.memo. The same persists after removing React.memo.

AbhayVAshokan avatar Aug 02 '21 05:08 AbhayVAshokan

The issue is also affecting me, just start using fragments

DanielRios549 avatar Oct 13 '21 15:10 DanielRios549

bump

refaelo avatar May 09 '22 05:05 refaelo

bump

meivinay avatar Jul 17 '22 13:07 meivinay

bump

vavra7 avatar Sep 25 '22 10:09 vavra7

mee to

rogeliotg avatar Oct 24 '22 10:10 rogeliotg

me too

hrvojegolcic avatar May 06 '23 16:05 hrvojegolcic

I still experience this bug with 4.27.1.

bryan-davis avatar May 17 '23 04:05 bryan-davis

Still seeing this in v4.27.8-2468a8735

uriklar avatar Jun 19 '23 09:06 uriklar

Still on 4.28.0-035a41c4e

gdfreitas avatar Aug 20 '23 02:08 gdfreitas