我正在尝试使用本指南实现一个反应表:
https://github.com/tannerlinsley/react-table/blob/master/docs/quickstart.md
在指南的某一点,它说使用React.useMemo创建数据:
const columns = React.useMemo(
() => [
{
Header: 'Column 1',
accessor: 'col1', // accessor is the "key" in the data
},
{
Header: 'Column 2',
accessor: 'col2',
},
],
[]
)
当我这样做时,我将这一行复制并粘贴到我的代码中(用我自己的数据替换数据(:
class Blog extends Component {
...
createTable() {
const cols = React.useMemo(
// copy and paste here
);
// more table creation code
return (
// jsx for table
);
}
...
}
但是当我运行这个时,它告诉我:
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
所以在谷歌搜索这个问题之后,我发现我需要在 React 功能中调用 useMemo。所以我创建了这个:
import React from 'react';
const getCols = () => {
return React.useMemo(() => [
{
Header: 'title',
accessor: 'titleCol'
},
{
Header: 'body',
accessor: 'bodyCol'
},
{
Header: 'last updated',
accessor: 'updatedAtCol'
}
], []);
};
export default getCols;
在我的博客课上:
class Blog extends Component {
...
createTable() {
const cols = getCols();
// more table creation code
return (
// jsx for table
);
}
...
}
但现在它告诉我:
React Hook "React.useMemo" is called in function "getCols" which is neither a React function component or a custom React Hook function
为什么它不是一个 React 函数?
更重要的是,调用useMemo(...(的正确方法是什么?
谢谢。
为什么它不是一个 React 函数?
这取决于您使用它的方式。getCols()
只是一个简单的函数调用返回jsx
,React 将其解释为这样。你必须render
它才能让 React 将其解释为功能组件
const cols = <getCols />; // this would be a React functional component
更重要的是,调用useMemo(...(的正确方法是什么?
首先要了解的是,在 React 中定义组件有两种方法——功能组件或类组件。
useMemo
是一个钩子。钩子用于向功能组件添加有状态逻辑。类组件,已经有了它们的生命周期方法(如componentDidMount
、componentDidUpdate
(。因此,钩子只能在功能组件或其他自定义钩子中使用,如您收到的两个警告中所述:
钩子只能在函数组件的主体内部调用。
React Hook ">React.useMemo" 在函数 "getCols" 中调用,它既不是 React 函数组件也不是自定义 React Hook 函数
useMemo
用于根据依赖关系记住某物的值。意味着一旦你使用useMemo
分配了一些东西,值/引用就不会改变,直到你的依赖项更新。
// `cols` will have the same value - `[ { Header: 'title ... ]`
// TILL the dependency array changes
const cols = React.useMemo(() => [
{
Header: 'title',
accessor: 'titleCol'
},
{
Header: 'body',
accessor: 'bodyCol'
},
{
Header: 'last updated',
accessor: 'updatedAtCol'
}
],
[] // <-- this is the dependency array,
// since it's empty, `cols` will only be initialized once
// if you had something like this instead
// [numberOfCols]
// i.e a variable in the dependency array,
// `cols` would update everytime `numberOfCols` updated
)
由于组件Blog
是一个类组件,因此您将无法直接在其中使用钩子。
有几种方法可以做到这一点:
方法 1:使博客成为功能组件
将整个Blog
组件转换为功能组件。您链接的文档似乎也在以这种方式使用它
const Blog = () => {
// now you can use `cols` somewhere in the body of your component
const cols = React.useMemo(() => {
...
}, [])
// this will return whatever you were returning from the
// `render` function in class component
return (
// jsx for table
)
}
方法 2:将列提取到功能组件中
将其用作另一个功能组件的一部分
class Blog extends Component {
createTable() {
// `cols` will be a React component now, not an array
// so probably not what you need,
// unless you want to use cols within that function
// and return the `jsx` to be rendered directly
const cols = <getCols />;
// more table creation code
return (
// jsx for table
);
}
}
方法 3:将其用作自定义挂钩
没有必要,但只是为了演示自定义钩子(您仍然需要将Blog
转换为功能组件(
对于文档
自定义 Hook 是一个 JavaScript 函数,其名称以 "use" 开头,可以调用其他 Hook。
const useTableCols = () => {
const cols = React.useMemo(() => {
...
}, [])
return cols
}
const Blog = () => {
const cols = useTableCols()
// do something with `cols`
}
错误消息不是要求您将代码放入"反应函数"中,而是要求您将其放入"函数组件"中。你的代码片段都是类组件(即,它们以class XYZ extends Component
开头(,钩子(包括useMemo
(在类组件中不起作用。
假设您要按照该教程中的步骤操作,则需要将代码编写为函数组件,而不是类组件。
const Blog = (props) => {
const cols = React.useMemo(() => [
{
Header: "title",
accessor: "titleCol",
},
{
Header: "body",
accessor: "bodyCol",
},
{
Header: "last updated",
accessor: "updatedAtCol",
},
], []);
// more table creation code
return (
// jsx for table
);
};
首先确保你已经安装了它。
npm install react-table
其次,请确保导入它:
import { useTable } from 'react-table'
第三,为什么不只看提供的示例(这里复制/粘贴的代码太多(:
https://github.com/tannerlinsley/react-table/tree/master/examples/basic/src