Learn AspNet
Learn AspNet

Reputation: 1612

Stop re-rendering the react functional component

I am using a third party component that re-renders every time state changes which is good but in some instances I do not want it to re-render even if the state changes. Is there a way to do using react functional component. I have read online and it says use shouldComponentUpdate() but I am trying to use functional component and tried using React.Memo but it still re-renders

Code

const getCustomers = React.memo((props) => {

useEffect(() => {

});

return (
<>
<ThirdPartyComponent>
do other stuff 
{console.log("Render Again")}
</ThirdPartyComponent>

</>
)
});

Upvotes: 3

Views: 4949

Answers (1)

Rodrigo Amaral
Rodrigo Amaral

Reputation: 1382

For props:

How do I implement shouldComponentUpdate?

You can wrap a function component with React.memo to shallowly compare its props:

const Button = React.memo((props) => {
  // your component
});

It’s not a Hook because it doesn’t compose like Hooks do. React.memo is equivalent to PureComponent, but it only compares props. (You can also add a second argument to specify a custom comparison function that takes the old and new props. If it returns true, the update is skipped.)

For state:

There's no build in way to achieve this, but you can try to extract your logic to a custom hook. Here's my attempt to only rerender when shouldUpdate returns true. Use it with caution, because it's the opposite of what React was designed for:

const useShouldComponentUpdate = (value, shouldUpdate) => {
  const [, setState] = useState(value);
  const ref = useRef(value);

  const renderUpdate = (updateFunction) => {
    if (!updateFunction instanceof Function) {
      throw new Error(
        "useShouldComponentUpdate only accepts functional updates!"
      );
    }

    const newValue = updateFunction(ref.current);

    if (shouldUpdate(newValue, ref.current)) {
      setState(newValue);
    }

    ref.current = newValue;
    console.info("real state value", newValue);
  };

  return [ref.current, renderUpdate];
};

You would use it like this:

  const [count, setcount] = useShouldComponentUpdate(
    0,
    (value, oldValue) => value % 4 === 0 && oldValue % 5 !== 0
  );

In this case, a rerender would occur (due to usages of setcount) if, and only if, shouldUpdate returns true. i.e., when value is multiple of 4 and the previous value is not multiple of 5. Play with my CodeSandbox example to see if that's really what you want.

Upvotes: 2

Related Questions