2
votes

I need to make an equivalent for the obsolete shouldComponentUpdate react lifecycle method with react hooks.

I have a Functional Components as it's called in this article which uses React.memo() to do it.

I just couldn't understand how to prevent the re-rendring of the component if only props is returned as a unique argument.

In others React.memo() examples (as in here) there is also a nextProps which is returned besides props and which is useful to compare with props to decide wether to let re-render the component or not.

Even when i add a second argument to be returned by the component , i always got just an empty plain js object.

Such as Functional Components aren't they always stateless so they won't keep any of the component's variables's values even those instanciated with the React.useState() ? So how we are supposed to know if props have changed ?!

this is the component:

import React, { useEffect, useRef, useState, memo } from "react";

const TinyEditor = (props, nextProps) => {
   return 'some jsx'
};

const MemoizedTinyEditor = memo(
  TinyEditor,
  (props, nextProps) => {
    // if(props.prop1 === nextProps.prop1) {
    //   // return true if you don't need re-render
    // }
    console.log("TinyEditor :: MEMO!!!!!!!!!!");
    return true;
  }
);
export default MemoizedTinyEditor;
1
Functional components are not longer meant to be just stateless, they can all contain states and lifecycles implemented with react hooks. As prop React.memo, it is kind of an HOC around your component, so it does know what props you passed and thee second argument to it is a function which is passed those props. However you cannot decide whether to re-render or not if the state changed. - Shubham Khatri
i also expected the state values will be kept as i'm using hooks but i wonder how is that possible as in each rendering the statement with useState() will be read (example const [textPageId, setTextPageId] = useState();". And BTW , i tried both updating the inner component state but also its parent's but got nothing with memo to compare with (no nextProps) in either cases. And i also got all the inner state variable prev values lost when it's a parent state update - Bardelman
react internally maintains a list of your hooks and the states associated with them. It also maintains whether thee component was rendered first time or it has subsequent re-renders, based on it it decides whether it will use the argument value to useState or return the previous value it had. Also state updates work in the same way - Shubham Khatri

1 Answers

2
votes

Have you tried what's mentioned in react's docs ?

By default it will only shallowly compare complex objects in the props object. If you want control over the comparison, you can also provide a custom comparison function as the second argument.

function MyComponent(props) {
  /* render using props */
}
function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
}
export default React.memo(MyComponent, areEqual);

React.memo

If you have tried this.. you should add attempted code to your question for others to review and figure out the issue. FYI this only works for props.. if the state of a component changes.. it will always rerender