I was reading the React docs and it recommended if you had some props that would be changed frequently, a good life cycle method to use would be shouldComponentUpdate.
My question is how would you use the useEffect approach with a functional component like the following?
This is my functional component:
function GenericIsUserLoggedInLink({ isLoggedIn, logOutUser, route, anchorText }) {
const [setProps] = useState({isLoggedIn: isLoggedIn, route: route, anchorText:anchorText });
console.log('setProps', setProps);
useEffect((nextProps, nextState) => {
if (setProps.isLoggedIn !== nextProps.setProps.isLoggedIn) {
return true;
}
if (setProps.route !== nextProps.setProps.route) {
return true;
}
if (setProps.anchorText !== nextProps.setProps.anchorText) {
return true;
}
return false;
});
if (isLoggedIn) {
if (anchorText === undefined) {
return <Link href="/"><a onClick={() => logOutUser()}>Log out!</a></Link>
} else if (anchorText) {
return <Link href={route}><a >{anchorText}</a></Link>
}
} else {
if (route === "/login") {
return <Link href="/login"><a >Log in!</a></Link>
}
return null
}
}
That was my take, but it didn't work! HA! Is there anyone who can provide insight?
UPDATE I followed Shubham's prescription—but ran into this?
SO i did this... But it feels hacky: I guess its not as I am leveraging lexical scoping
var comparator;
const GenericIsUserLoggedInLink = React.memo(({ isLoggedIn, logOutUser, route, anchorText }) => {
comparator = (prevProps, nextProps) => {
if (prevProps.isLoggedIn !== nextProps.setProps.isLoggedIn) {
return true;
}
if (prevProps.isLoggedIn !== nextProps.setProps.route) {
return true;
}
if (prevProps.anchorText !== nextProps.setProps.anchorText) {
return true;
}
return false;
}
if (isLoggedIn) {
if (anchorText === undefined) {
return <Link href="/"><a onClick={() => logOutUser()}>Log out!</a></Link>
} else if (anchorText) {
return <Link href={route}><a >{anchorText}</a></Link>
}
} else {
if (route === "/login") {
return <Link href="/login"><a >Log in!</a></Link>
}
return null
}
}, comparator);
useEffect
is not an appropriate hook as an alternative to shouldComponentUpdate
for functional components.
Rather you need to use React.memo in order to prevent re-rendering. Also you don't need to maintain a state to compare previous and current props.
const comparator = (prevProps, nextProps) => {
if (prevProps.isLoggedIn !== nextProps.setProps.isLoggedIn) {
return true;
}
if (prevProps.route !== nextProps.setProps.route) {
return true;
}
if (prevProps.anchorText !== nextProps.setProps.anchorText) {
return true;
}
return false;
}
const GenericIsUserLoggedInLink = React.memo(({ isLoggedIn, logOutUser, route, anchorText }) => {
if (isLoggedIn) {
if (anchorText === undefined) {
return <Link href="/"><a onClick={() => logOutUser()}>Log out!</a></Link>
} else if (anchorText) {
return <Link href={route}><a >{anchorText}</a></Link>
}
} else {
if (route === "/login") {
return <Link href="/login"><a >Log in!</a></Link>
}
return null
}
}, comparator);