1

According to my understanding, when CIsTrue state is updated, the ToolbarButton with "SecondButton" should not re-render. However, when I checked console logs, it does re-render. What am I missing? Does it have something to do with the Icon prop being a React components? I tried to add a check in the React.memo function to compare them but I'm not sure if that's enough.

function App() {

  const [AIsTrue] = useState(true);
  const [BIsTrue] = useState(true);
  const [CIsTrue] = useState(true);

  return (
       <ToolbarComponent
            AIsTrue={AIsTrue}
            BIsTrue={BIsTrue}
            CIsTrue={CIsTrue}
        />
  );
}

export default App;

import { ReactComponent as MyIcon } from 'somepath.svg';
import { ReactComponent as MyOtherIcon } from 'somepath2.svg';

export interface ToolbarComponentProps {
  AIsTrue: boolean;
  BIsTrue: boolean;
  CIsTrue: boolean;
}

export const ToolbarComponent: React.FunctionComponent<ToolbarComponentProps> = (props) => {
  const { AIsTrue, BIsTrue, CIsTrue } = props;

  return (
    <Stack>
      <ToolbarButton
        text="FirstButton"
        icon={<MyIcon />}
        visible={AIsTrue || BIsTrue || CIsTrue }
      />

      <ToolbarButton
        text="SecondButton"
        icon={<MyOtherIcon />}
        visible={BIsTrue}
      />

    </Stack>
  );
};

    export interface IToolbarButtonProps {
       text?: String;
       icon: React.ReactNode;
       visible?: Boolean;
    }

    export const ToolbarButton: React.FunctionComponent<IToolbarButtonProps> = React.memo(
      (props) => {
    const { text, icon, visible } = props;
    if (visible) {
       buttonClass = blah
    }

    console.log('I rendered - ' + text);

    return (
      <Button className={buttonClass}>
        <Stack horizontal>
          {icon}
          <Text>{text}</Text>
        </Stack>
      <Button>
    );
  },
  (prevProps, nextProps) => {
    if (prevProps.icon === nextProps.icon) {
      return true; // props are equal
    }
    return false; // props are not equal -> update the component
  },
);
Anavi Lohia
  • 31
  • 1
  • 3
  • Hi, could you please share a minimum reproducible code/example of above in online IDE like the codesandbox - this will help the community to resolve it quickly. – ypahalajani Aug 21 '21 at 07:21

1 Answers1

1

I am not sure but maybe it is re-rendering because of this:

icon={<MyOtherIcon />}

Try commenting it for a while and check if it fixes the problem. It could be whatever that JSX returns is a different reference on each render.


To fix it try passing as

icon={MyOtherIcon}

Then you can render it inside your component as

let Icon = props.icon;
<Icon/>
Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90