Почему React.useMemo (...) не работает в моей функции React? - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь реализовать таблицу реакций, используя это руководство:

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

Итак, после поиска этой проблемы я понял, что мне нужно вызвать useMemo в функции React. Итак, я создал это:

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 (...)?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 19 июня 2020

Сообщения об ошибках не просят вас поместить код в «функцию реакции», они просят вас поместить его в «функциональный компонент». Все ваши фрагменты кода являются компонентами класса (ie, они начинаются с 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
  );
};

0 голосов
/ 19 июня 2020

Почему это не функция React?

Это зависит от того, как вы ее используете. getCols() - это просто простой вызов функции, возвращающий jsx, и React интерпретирует его так. Вам нужно render, чтобы React интерпретировал его как функциональный компонент

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

Что еще более важно, как правильно вызывать useMemo (...)?

Первое, что нужно понять, это то, что есть два способа определения компонентов в React - функциональные компоненты или компоненты класса .

useMemo - это хук . Хуки используются для добавления логики c с отслеживанием состояния к функциональным компонентам. Компоненты класса уже имеют это с их методами жизненного цикла (например, 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 в функциональный компонент)

Для документов

Пользовательский крючок - это функция JavaScript, имя которой начинается с «использовать» и которые могут вызывать другие хуки.

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

   return cols
}


const Blog = () => {
   const cols = useTableCols()
   
   // do something with `cols`
}
0 голосов
/ 19 июня 2020

Сначала убедитесь, что вы его действительно установили.

npm install react-table

Во-вторых, убедитесь, что вы его импортируете:

import { useTable } from 'react-table'

В-третьих, почему бы просто не взглянуть на предоставленные примеры (здесь слишком много кода для копирования / вставки):

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...