开发者问题收集

React 的 useMemo 方法导致无效的钩子调用

2019-09-12
2511

该场景非常简单,up 可以直接进入代码,而无需阅读以下描述。

我正在创建一个非常简单的 React 应用,它呈现一个包含单个 h3 元素的列表(每个列表都有一个唯一的 id)。单击 h3 元素时,其文本将从“未单击”更改为“单击”。 这是通过根组件 App 中的 useState 实现的。状态跟踪被单击组件的 id。单击​​ h3 元素时,它将触发回调,将单击的 id 设置为其自己的 id。问题是,当触发单击时,所有自定义列表组件都会重新渲染。我试图使用 React 的 useMemo 来防止重新渲染,但收到此错误:

无效的钩子调用。钩子只能在函数组件的主体内调用。这可能是由于以下原因之一导致的: 1. 您的 React 和渲染器版本可能不匹配(例如 React DOM) 2. 您可能违反了 Hooks 规则 3. 您可能在同一个应用中拥有多个 React 副本

// App.js
import React from 'react';
import ListElement from './ListElement'
const listOfID = [1,2,3,4,5,6]

function App() {

  const [clicked, updateClicked] = React.useState(null)
  return (
    <ul>
      {listOfID.map((id, index )=> < ListElement key={index} id={id} clicked={id == clicked} updateClicked={updateClicked}/>)}
    </ul>
  )
}

// ListElement.js
import React from 'react';

export default React.useMemo((props) => {
    console.log("rendered")
    return (
        <li>
            <h3 onClick={() => props.updateClicked(props.id)}>{(props.id == props.clicked) ? "clicked" : "not clicked"}</h3>
        </li>
    )
},
    (prevProps, nextProps) => {
        return prevProps.clicked == nextProps.clicked
    }
);
1个回答

useMemo 是一个 hook 。我相信您指的是 React.memo ,以防止 Components 中无用的 renders

export default React.memo((props) => {
    console.log("rendered")
    return (
        <li>
            <h3 onClick={() => props.updateClicked(props.id)}>{(props.id == props.clicked) ? "clicked" : "not clicked"}</h3>
        </li>
    )
},
    (prevProps, nextProps) => {
        return prevProps.clicked == nextProps.clicked
    }
);
Dupocas
2019-09-12