[英]React Using useState/Hooks In HOC Causes Error "Hooks can only be called inside of the body of a function component"
[英]React Hooks Error: Hooks can only be called inside the body of a function component
使用useState
掛鈎時出現此錯誤。 我有它的基本形式,查看反應文檔以供參考,但仍然收到此錯誤。 我已經准備好迎接面掌時刻了...
export function Header() {
const [count, setCount] = useState(0)
return <span>header</span>
}
新版本的react-hot-loader
現已發布, 鏈接。 Hooks 現在可以開箱即用了。 感謝作者,theKashey。
看看這個樣板https://github.com/ReeganExE/react-hooks-boilerplate
首先,確保你安裝了react@next
和react-dom@next
。
然后檢查您是否正在使用react-hot-loader
。
在我的情況下,禁用熱加載器和 HMR 可以讓它工作。
請參閱https://github.com/gaearon/react-hot-loader/issues/1088 。
引:
是的。 RHL 與鈎子 100% 不兼容。 這背后有幾個原因:
SFC 正在轉換為 Class 組件。 有理由 - 能夠在 HMR 上強制更新,只要 SFC 上沒有“更新”方法。 我正在尋找強制更新的其他方式(就像這樣。所以 RHL 正在殺死 SFC。
“熱替換渲染”。 RHL 正在嘗試做 React 的工作,渲染新舊應用程序,合並它們。 所以,顯然,現在已經壞了。
我將起草一份 PR,以緩解這兩個問題。 它會起作用,但不是今天。
有一個更合適的修復方法,它可以工作 - 冷 API
您可以為任何自定義類型禁用 RHL。
import { cold } from 'react-hot-loader';
cold(MyComponent);
在組件源代碼中搜索"useState/useEffect"
,並“冷”它。
根據 react-hot-loader 維護者的更新,您可以嘗試react-hot-loader@next
並將配置設置如下:
import { setConfig } from 'react-hot-loader';
setConfig({
// set this flag to support SFC if patch is not landed
pureSFC: true
});
感謝@loganfromlogan 的更新。
我的問題是忘記更新react-dom
模塊。 見問題。
有同樣的問題。 我的問題與 React Router 相關。 我不小心使用了
<Route render={ComponentUsingHooks} />
代替
<Route component={ComponentUsingHooks} />
我能夠通過在組件文件中導入 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 庫沒有耦合,允許更自然的函數式編程和測試。
我在使用Parcel 的 Hot Module Replacement時遇到了這個錯誤,並通過將react-dom
更新為它的 alpha 版本來修復:
yarn add react-dom@16.7.0-alpha.0
只是為了詳細說明@rista404 的答案,包括react
(可能還有react-dom
)的重復版本將產生相同的錯誤,具體取決於您使用鈎子的位置。 這里有兩個例子...
react
在其dependencies
,這可能誤作為react
通常應該是對等的依賴。 如果npm
沒有自動使用您的本地版本對此版本進行重復數據刪除,您可能會看到此錯誤。 這就是@rista404 所指的。npm link
一個包,該包在其devDependencies
或dependencies
中包含react
。 現在,對於此包中的模塊,如果它們從其本地node_modules
目錄而不是父項目的目錄中提取不同版本的react
,您可能會看到錯誤。 后者可以用捆綁在固定webpack
使用resolve.alias
是這樣的...
resolve: {
alias: {
'react': path.resolve(__dirname, 'node_modules/react'),
'react-dom': path.resolve(__dirname, 'node_modules/react-dom')
}
}
這將確保react
總是從父項目的拉動node_modules
目錄。
我的問題確實是react-hot-loader 。
您可以使用像這樣的cold
方法為單個組件而不是整個應用程序禁用 react-hot-loader :
import { cold } from 'react-hot-loader'
export const YourComponent = cold(() => {
// ... hook code
return (
// ...
)
})
或者
export default cold(YourComponent)
對於那些誰碰到這個問題來使用MobX和包裝用零部件時observer
,請確保您使用mobx-react-lite
,而不是mobx-react
。
5 月 29 日更新
從mobx-react
6.0.0
開始, mobx-react
現在支持基於鈎子的組件,因此,不再需要使用mobx-react-lite
(如果那是您的問題)。
如果您在使用 npm 鏈接時遇到此問題,則另一種解決方案:
您可以按照此處的說明在庫中進行npm link
react: https : //reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react
或者在你的庫中將 react 設置為 peerDependency 然后使用npm link --only=production
為react-hot-loader
找到了這個解決方法,而修復它的 PR 是入站的。
將調用鈎子的函數包裝在React.memo
,如果它沒有改變,則防止熱重載。
const MyFunc = React.memo(({props}) => {...
我的問題如下:
我在做: ReactDOM.render(Example(), app);
而我應該做的是: ReactDOM.render(<Example />, app);
對於紗線工作區的其他用戶,這是我的情況以及我是如何解決的。
Invalid Hook Call Warning上的 Facebook 文檔沒有提到紗線工作區,所以我認為我的配置是正確的。 但事實並非如此。 您只能通過在所有包中使用相同的版本來修復錯誤。
在上面的示例中,您必須將 react 版本從“foo”提升到 16.10.1,以便它與“bar”中的 react 版本匹配。
獎勵:請參閱 GitHub 上的此討論,了解在 Internet 上卸下的一組精美的情感包袱。
好吧,在我的情況下,我在 useEffect 中調用 useSelector !
如果您正在使用 Create React App,您還必須使用 react 和 react-dom 版本更新"react-scripts"
版本。
"react-scripts": "2.1.5",
"react": "^16.8.1",
"react-dom": "^16.8.1",
這種組合效果很好。
對我來說,這是因為我有一個新版本的 react (16.8.6) 和一個舊版本的 react-dom (16.6.1)。
將兩者都升級到 @latest (16.8.6) 修復了錯誤。
我一直在使用react-electron-boilerplate應用程序遇到這個問題。
由於這個不幸的錯誤,許多插件和庫(如 Material-UI)無法在我的項目中使用,經過大量搜索,我可以解決問題:
我剛剛將react
和react-dom
升級到了最新版本。
這個命令完成了工作!
yarn add react@latest react-dom@latest
檢查react
和react-dom
版本嚴格相等。 注意版本上的抑揚符^
符號。
"17.0.0"
不能與"^17.0.0"
相同
npm - Carret 范圍: https : //github.com/npm/node-semver#caret-ranges-123-025-004 React - 變更日志: https : //github.com/facebook/react/blob/main/CHANGELOG。醫學博士
這是使用 -E 或 --save-exact 更好地安裝軟件包的原因之一
npm install --save --save-exact <package@vesion>
將 package.json react-dom 版本更新為 react
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.