为什么React.useMemo(...)在我的React函数中不起作用? [英] Why isn't React.useMemo(...) working in my React function?

查看:245
本文介绍了为什么React.useMemo(...)在我的React函数中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用此指南来实现反应表:

I'm trying to implement a react-table using this guide:

https://github.com/tannerlinsley/react -table/blob/master/docs/quickstart.md

在指南中,它指出要使用React.useMemo创建数据:

At one point in the guide, it says to create your data using React.useMemo:

const columns = React.useMemo(
  () => [
    {
      Header: 'Column 1',
      accessor: 'col1', // accessor is the "key" in the data
    },
    {
      Header: 'Column 2',
      accessor: 'col2',
    },
  ],
  []
)

执行此操作时,我将此行复制并粘贴到我的代码中(用我自己的数据替换数据):

When I do this, I copy and paste this line into my code (replacing the data with my own data):

class Blog extends Component {

...

createTable() {

    const cols = React.useMemo(
        // copy and paste here
    );

    // more table creation code

    return (
        // jsx for table
    );
}

...

}

但是当我运行它时,它告诉我:

But when I run this, it tells me:

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.所以我创建了这个:

So after googling this problem, I gathered that I need to call useMemo in a React funcion. So I created this:

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;

在我的Blog类中:

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函数?

Why isn't it a React function?

更重要的是,调用useMemo(...)的正确方法是什么?

More importantly, what is the proper way to call useMemo(...)?

谢谢.

推荐答案

为什么它不是React函数?

Why isn't it a React function?

这取决于您的使用方式. getCols()只是返回jsx的简单函数调用,React如此解释它.您必须render使其获得React才能将其解释为功能组件

It depends on the way you are using it. getCols() is just a simple function call returning jsx and React interprets it as so. You have to render it to get React to interpret it as a functional component

 const cols = <getCols />; // this would be a React functional component

更重要的是,调用useMemo(...)的正确方法是什么?

More importantly, what is the proper way to call useMemo(...)?

首先要了解的是,有两种方法可以在React中定义组件-功能组件或类组件.

First thing to understand is that there are two ways to define components in React - functional components or class components.

useMemo钩子.挂钩用于向功能组件添加状态逻辑.类组件已经具有其生命周期方法(例如componentDidMountcomponentDidUpdate).因此,挂钩只能 用于功能组件或其他自定义挂钩中,如您获得的两个警告所述:

useMemo is a hook. Hooks are used to add stateful logic to functional components. Class components, already have that with their lifecycle methods (like componentDidMount, componentDidUpdate). So hooks can only be used inside a functional component or another custom hook, as mentioned in the two warnings you got:

只能在函数组件的主体内部调用钩子.

Hooks can only be called inside of the body of a function component.

React Hook"React.useMemo";在函数"getCols"中调用它既不是React函数组件也不是自定义的React Hook函数

React Hook "React.useMemo" is called in function "getCols" which is neither a React function component or a custom React Hook function

useMemo 用于基于在依赖项上.意味着一旦您使用useMemo分配了某些内容,值/引用就不会更改,直到您的依赖项更新为止.

useMemo is used to memoize the value of something, based on the dependencies. Means once you assign something using useMemo, the value/reference won't change till your dependencies update.

   // `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是类组件,因此您将无法直接在其内部使用钩子.

Since your component Blog is a class component, you won't be able to use hooks inside it directly.

有两种方法可以做到:

方法1:使Blog成为功能组件

将整个Blog组件转换为功能组件.您链接的文档似乎也在以这种方式使用

Convert the whole Blog component as a functional component. The docs that you've linked also seem to be using it this way

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提取到功能组件中

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

Use it as part of another functional component

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转换为功能组件)

Unnecessary, but just to demonstrate a custom hook (you'll still need to convert Blog into a functional component)

对于文档

自定义挂钩是一种JavaScript函数,其名称以"use"开头,并且可以调用其他挂钩.

A custom Hook is a JavaScript function whose name starts with "use" and that may call other Hooks.

const useTableCols = () => {
   const cols = React.useMemo(() => {
     ...
   }, [])

   return cols
}


const Blog = () => {
   const cols = useTableCols()
   
   // do something with `cols`
}

这篇关于为什么React.useMemo(...)在我的React函数中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆