【问题标题】:How would you implement shouldComponentUpdate using useEffect in React?你将如何在 React 中使用 useEffect 实现 shouldComponentUpdate?
【发布时间】:2019-10-16 04:43:00
【问题描述】:

我正在阅读 React 文档,它建议如果你有一些会经常更改的道具,一个好的生命周期方法是shouldComponentUpdate

我的问题是您如何将useEffect 方法与如下功能组件一起使用?

这是我的功能组件:

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
 }
}

这是我的想法,但它没有用!哈!有没有人可以提供见解?

更新 我遵照 Shubham 的处方,但遇到了这个问题?

所以我这样做了... 但感觉很hacky: 我想这不是因为我正在利用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中的返回true/false是否与组件渲染有关。因为,如果我们在 useEffect 中返回一个函数,它将作为清理函数运行,但是,我认为它与布尔值无关。
  • 另外,我不确定 nextProps 是否在 useEffect 中可用。所以,我会把它留给更好的人来澄清
  • 为什么首先需要“setProps”状态和这些检查?您永远不会在渲染阶段使用该状态,并且您 useEffect 没有任何用处。如果您只留下if (isLoggedIn) { ... } 部分会出现什么问题?

标签: reactjs state react-hooks high-order-component react-lifecycle-hooks


【解决方案1】:

useEffect 不是功能组件的 shouldComponentUpdate 替代方案的合适钩子。

您需要使用 React.memo 来防止重新渲染。此外,您不需要维护状态来比较以前和当前的道具。

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);

【讨论】:

  • 非常感谢!对此,我真的非常感激!我用你的补充更新了我的问题以及随后发生的事情。那么React.memo 应该加快速度吗?我想在production 这会更快?
  • 注意比较器功能。当它返回 true 时,组件不会被重新渲染。将其称为 areEqual 或 shouldNotRerender 以便更好地理解。
猜你喜欢
  • 2019-06-30
  • 2017-01-18
  • 2021-12-09
  • 2015-10-16
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
相关资源
最近更新 更多