0

我正在尝试使用本指南实现一个反应表:

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(...) 的正确方法是什么?

谢谢。

4

3 回答 3

1

为什么它不是 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是类组件,因此您将无法直接在其中使用挂钩。

有几种方法可以做到这一点:

方法一:让博客成为功能组件

将整个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:将 cols 提取到功能组件中

将其用作另一个功能组件的一部分

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`
}
于 2020-06-19T05:25:57.813 回答
0

错误消息不是要求您将代码放入“反应函数”中,而是要求您将其放入“功能组件”中。您的代码片段都是类组件(即,它们以 开头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
  );
};

于 2020-06-19T03:46:24.670 回答
-1

首先确保您已经实际安装了它。

npm install react-table

其次,确保您正在导入它:

import { useTable } from 'react-table'

第三,为什么不只看提供的示例(这里的代码太多,无法复制/粘贴):

https://github.com/tannerlinsley/react-table/tree/master/examples/basic/src

于 2020-06-19T03:31:35.037 回答