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, что обеспечивает более естественное функциональное программирование и тестирование.
Ответ 4
Я столкнулся с этой ошибкой при использовании Parcel Hot Module Replacement и исправил ее путем обновления alpha-версии react-dom
:
yarn add [email protected]
Смотрите эту проблему.
Ответ 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
), вы получите ту же ошибку в зависимости от того, где вы используете свои хуки. Вот два примера...
- Внешняя зависимость включает в себя другую версию
react
в своих dependencies
, вероятно, по ошибке, поскольку react
обычно должна быть зависимостью от сверстников. Если npm
не выполняет автоматическую дедупликацию этой версии с вашей локальной версией, вы можете увидеть эту ошибку. Это то, на что ссылался @rista404. - Вы
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);
Ответ 13
Для меня это происходило потому, что у меня была новая версия реакции (16.8.6) и старая версия реагирования (16.6.1).
https://reactjs.org/warnings/invalid-hook-call-warning.html#mismatching-versions-of-react-and-react-dom
Обновление до @latest (16.8.6) исправило ошибку.
Ответ 14
Для других пользователей рабочих областей пряжи, здесь моя ситуация и как я понял это.
Документы Facebook на Invalid Hook Call Warning ничего не говорят о рабочих местах пряжи, поэтому я предположил, что моя конфигурация была правильной. Но это не так. Вы можете исправить ошибку, используя одну и ту же версию для всех ваших пакетов.
В приведенном выше примере вы должны изменить версию реакции с "foo" на 16.10.1, чтобы она соответствовала версии реагирования с "bar".
Бонус: смотрите эту дискуссию на GitHub, чтобы увидеть прекрасную коллекцию эмоционального багажа, загруженную в Интернете.
Ответ 15
обновить package.json версию про-дима как реагировать