Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent rerender of sibling component which initiates a useState in wrapper component

I am not very experienced with React but I have a very simple Setup.

export default function App() {
  const [title, setTitle] = useState("still-empty");

  const myFunction = title => {
    setTitle(title);
  };

  return (
    <div className="App">
      <ComponentA myFunction={myFunction} />
      <br />
      <br />
      <ComponentB title={title} />
    </div>
  );
}



const ComponentA = ({ myFunction }) => {
  console.log("Rendering Component A");

  return (
    <div onClick={() => myFunction(Math.random() * 1000)}> Component A </div>
  );
};

export default ComponentA;


const ComponentB = ({ title }) => {
  return <div> Title : {title}</div>;
};

export default ComponentB;

Here is a sandbox to test this: https://codesandbox.io/s/musing-cookies-g7szr

See that if you click on "ComponentA", that exact ComponentA gets rerendered (you can see it in console) although no props are changed on this component. This is a simplified example of my real use case. In my real use case, ComponentA is a map where a lot of stuff (zoom, center) will be reset. I want to prevent these resets and also the 1 second it takes for rerendering. Therefor I present this simplified example.

So how do I pass an information from ComponentA to ComponentB, without rerendering ComponentA itself? Thanks for helping out here.

like image 997
schingeldi Avatar asked Nov 03 '25 07:11

schingeldi


1 Answers

use useCallback in Parent so that the function is not created again and again but only on initial render. use React.memo so that when no props are changed the component wont re-render.

App

export default function App() {
  const [title, setTitle] = useState("still-empty");

  const myFunction = useCallback(title => {
    setTitle(title);
  }, []);

  return (
    <div className="App">
      <ComponentA myFunction={myFunction} />
      <br />
      <br />
      <ComponentB title={title} />
    </div>
  );
}

ComponentA

import React, { memo } from "react";

const ComponentA = ({ myFunction }) => {
  console.log("Rendering Component A");

  return (
    <div onClick={() => myFunction(Math.random() * 1000)}> Component A </div>
  );
};

export default memo(ComponentA);

Working demo is here: https://codesandbox.io/s/affectionate-boyd-v7g2t?file=/src/App.js

like image 58
gdh Avatar answered Nov 06 '25 02:11

gdh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!