React Hooks Error: хуки могут быть вызваны только внутри тела компонента функции

Я получаю эту ошибку при использовании useState. У меня есть это в его основной форме, глядя на реактивные документы для справки, но я все еще получаю эту ошибку. Я готов к моменту ладони лица...

export function Header() {
  const [count, setCount] = useState(0)
  return <span>header</span>
}

Ответы

Ответ 1

Обновлено: 2018 декабрь

Вышла новая версия react-hot-loader, ссылка. Крючки теперь работают из коробки. Спасибо автору, Каше.

Проверьте этот шаблон https://github.com/ReeganExE/react-hooks-boilerplate

  • React Hooks
  • React Hot Loader
  • Webpack, Babel, ESLint Airbnb

Предыдущий ответ:

Во-первых, убедитесь, что вы установили [email protected] и [email protected].

Затем проверьте, используете ли вы react-hot-loader или нет.

В моем случае отключите горячий загрузчик и HMR может заставить его работать.

См. Https://github.com/gaearon/react-hot-loader/issues/1088.

Цитируется:

Да. БРЗ на 100% не совместимо с крючками. За этим стоит всего несколько причин:

SFC переводятся в компоненты класса. Есть причина - иметь возможность принудительного обновления на HMR, пока на SFC нет метода "обновления". Я ищу другой способ принудительного обновления (как это. Так что RHL убивает SFC.

"HotReplacementRender". БРЗ пытается выполнить работу React и отрисовать старое и новое приложение, чтобы объединить их. Итак, очевидно, что сломано сейчас.

Я собираюсь составить пиар, чтобы смягчить обе проблемы. Это будет работать, но не сегодня.

Есть более правильное решение, которое будет работать - холодный API

Вы можете отключить БРЗ для любого пользовательского типа.

import { cold } from 'react-hot-loader';

cold(MyComponent);

Ищите "useState/useEffect" в исходном коде компонента и " "useState/useEffect" " его.

Обновлено:

В соответствии с обновлениями, предоставленными сопровождающим реагирующим-горячим загрузчиком, вы можете попробовать [email protected] и установить конфигурацию следующим образом:

import { setConfig } from 'react-hot-loader';

setConfig({
  // set this flag to support SFC if patch is not landed
  pureSFC: true
});

Спасибо @loganfromlogan за обновление.

Ответ 2

Моя проблема была в том, что я забыл обновить модуль react-dom. Смотрите вопрос.

Ответ 3

Я смог решить эту проблему, импортировав примитивные хуки React в файл компонента, а затем передав их в мои пользовательские хуки. По какой-то причине ошибка возникает только тогда, когда я импортирую ловушку React (например, useState) в мой файл настраиваемой ловушки.

Я импортирую useState в мой файл компонента:

import React, {useState} from 'react'; // import useState

import {useCustomHook} from '../hooks/custom-hook'; // import custom hook

const initialState = {items: []};
export default function MyComponent(props) {
    const [state, actions] = useCustomHook(initialState, {useState});
    ...
}

Тогда в моем файле хука:

// do not import useState here

export function useCustomHook(initialValue, {useState}) {
    const [state, setState] = useState(initialValue || {items: []});

    const actions = {
        add: (item) => setState(currentState => {
            const newItems = currentState.items.concat([item]);
            return {
                ...currentState,
                items: newItems,
            };
        }),
    };

    return [state, actions];
}

Этот метод улучшил тестируемость моих хуков, потому что мне не нужно макетировать библиотеку React для обеспечения примитивных хуков. Вместо этого мы можем передать ложный хук useState прямо в пользовательскую хук-функцию. Я думаю, что это улучшает качество кода, поскольку ваши пользовательские хуки теперь не связаны с библиотекой React, что обеспечивает более естественное функциональное программирование и тестирование.

Ответ 5

У меня возникла проблема в monorepo, где пакет docz использовалact [email protected] а в окончательном выходном пакете было две версии реакции.

Выпуск на Github

Исправлено, удалив пакет 😅

Ответ 6

Проблема для меня была действительно реагировать-горячий загрузчик.

Вы можете отключить реакцию горячей загрузки для одного компонента, а не для всего приложения, используя cold метод следующим образом:

import { cold } from 'react-hot-loader'

export const YourComponent = cold(() => {

  // ... hook code

  return (
    // ...
  )
})

ИЛИ ЖЕ

export default cold(YourComponent)

Ответ 7

Была такая же проблема. Моя проблема была связана с React Router. Я случайно использовал

<Route render={ComponentUsingHooks} />

вместо

<Route component={ComponentUsingHooks} />

Ответ 8

Для тех, кто сталкивался с этой проблемой при использовании MobX и обертывании компонента с observer, убедитесь, что вы используете mobx-react-lite вместо mobx-react.

29 мая ОБНОВЛЕНИЕ

Начиная с mobx-react 6.0.0, компоненты, основанные на ловушке , теперь поддерживаются mobx-реагировать, таким образом, больше нет необходимости использовать mobx-react-lite (если это была ваша проблема).

Ответ 9

Если уточнить ответ @rista404, в том числе дублирующиеся версии react (и, возможно, react-dom), вы получите ту же ошибку в зависимости от того, где вы используете свои хуки. Вот два примера...

  1. Внешняя зависимость включает в себя другую версию react в своих dependencies, вероятно, по ошибке, поскольку react обычно должна быть зависимостью от сверстников. Если npm не выполняет автоматическую дедупликацию этой версии с вашей локальной версией, вы можете увидеть эту ошибку. Это то, на что ссылался @rista404.
  2. Вы npm link пакет, который включает в себя react в своих devDependencies или dependencies. Теперь для модулей в этом пакете вы можете увидеть ошибки, если они node_modules другую версию react из своего локального node_modules а не из родительского проекта.

Последнее может быть исправлено при связывании с webpack с помощью resolve.alias например так...

    resolve: {
        alias: {
            'react': path.resolve(__dirname, 'node_modules/react'),
            'react-dom': path.resolve(__dirname, 'node_modules/react-dom')
        }
    }

Это гарантирует, что react всегда извлекается из каталога родительского проекта node_modules.

Ответ 10

нашел этот обходной путь для react-hot-loader то время как этот PR, чтобы исправить это входящий.

Оберните функцию, которая вызывает перехватчики в React.memo, предотвращая горячую перезагрузку, если она не изменилась.

const MyFunc = React.memo(({props}) => {...

Кредит за решение: https://github.com/gatsbyjs/gatsby/issues/9489

Ответ 11

Если вы используете приложение Create React, вам необходимо обновить версию "react-scripts" также с версиями реагировать и реагировать.

 "react-scripts": "2.1.5",
 "react": "^16.8.1",
 "react-dom": "^16.8.1",

эта комбинация работает отлично.

Ответ 12

Моя проблема заключалась в следующем:

Я делал: ReactDOM.render(Example(), app);

Принимая во внимание, что я должен был сделать: ReactDOM.render(<Example/>, app);

Ответ 14

Для других пользователей рабочих областей пряжи, здесь моя ситуация и как я понял это.

Документы Facebook на Invalid Hook Call Warning ничего не говорят о рабочих местах пряжи, поэтому я предположил, что моя конфигурация была правильной. Но это не так. Вы можете исправить ошибку, используя одну и ту же версию для всех ваших пакетов.

В приведенном выше примере вы должны изменить версию реакции с "foo" на 16.10.1, чтобы она соответствовала версии реагирования с "bar".

Бонус: смотрите эту дискуссию на GitHub, чтобы увидеть прекрасную коллекцию эмоционального багажа, загруженную в Интернете.

Ответ 15

обновить package.json версию про-дима как реагировать