React.useMemo无法阻止重新渲染

时间:2019-10-22 01:58:26

标签: javascript reactjs typescript react-hooks

我有以下简单组件:

const Dashboard = () => {
  const [{ data, loading, hasError, errors }] = useApiCall(true)

  if (hasError) {
    return null
  }

  return (
    <Fragment>
      <ActivityFeedTitle>
      <ActivityFeed data={data} isLoading={loading} />
    </Fragment>
  )
}

export default Dashboard

我想阻止ActivityFeedTitle组件的所有重新渲染,以便在加载时仅渲染一次。我的理解是,我应该能够将React.useMemo钩子与空的依赖项数组配合使用来实现此目的。我被return更改为:

return (
    <Fragment>
        {React.useMemo(() => <ActivityFeedTitle>, [])}
        <ActivityFeed data={data} isLoading={loading} />
    </Fragment>
)

就我而言,这应该阻止该组件的所有重新出售吗?但是,ActivityFeedTitle组件仍会在每次渲染Dashboard组件时重新渲染。

我想念什么?

编辑:

使用React.memo仍然会导致相同的问题。我尝试按照以下步骤记忆我的ActivityFeedTitle组件:

const Memo = React.memo(() => (
  <ActivityFeedTitle />
))

然后在我的返回中使用它:

return (
    <Fragment>
        {<Memo />}
        <ActivityFeed data={data} isLoading={loading} />
    </Fragment>
)

发生相同的问题。我还尝试将() => false的以下内容作为React.memo的第二个参数传递,但这也没有用。

6 个答案:

答案 0 :(得分:1)

使用React.memo()来根据道具来记忆组件。

React.memo(function ActivityFeedTitle(props) {
  return <span>{props.title}</span>
})

注意:

  

此方法仅作为性能优化存在。不要依靠它来“阻止”渲染,因为这可能会导致错误。

答案 1 :(得分:0)

您对useMemo的使用不正确。

来自react hooks文档:

  

传递“创建”函数和一系列依赖项。 useMemo将   仅当其中一个依赖项具有   改变了。此优化有助于避免进行昂贵的计算   每个渲染。

     

如果未提供任何数组,则将在每个渲染器上计算一个新值。

您需要在此处使用useMemo之类的useEffect来计算值,而不是渲染组件。

React.memo

React.memo()是您要寻找的。除非道具发生变化,否则它会阻止重新渲染。

答案 2 :(得分:0)

您错误地使用了React.memo。 React.memo接受组件作为参数。

const Memo = React.memo(ActivityFeedTitle />);

我建议您将状态(即数据和isLoading)移动到ActivityFeed组件,这样您的仪表板组件就不会重新呈现,也不需要将标题组件包装在备忘录中。

答案 3 :(得分:0)

您可以使用React.memo并在定义组件的位置而不是在创建该组件的实例的位置使用它。您可以在ActivityFeedTitle组件中使用

const ActivityFeedTitle = React.memo(() => {
  return (
   //your return
  )
})

希望有帮助

答案 4 :(得分:0)

传递给React.memo的第二个参数将需要返回true,以防止重新渲染。而不是计算组件是否应该更新,而是确定要传递的道具是否相等。

答案 5 :(得分:0)

这是因为渲染父对象会导致大部分子对象重新渲染。更好的优化方法是将数据获取逻辑放置在ActivityFeed组件中或包装ActivityFeed的HOC中。

相关问题