React Native 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用
Posted
技术标签:
【中文标题】React Native 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用【英文标题】:React Native Error: Invalid hook call. Hooks can only be called inside of the body of a function component 【发布时间】:2022-01-09 19:41:32 【问题描述】:我正在和一些朋友编写一个国际象棋应用程序,现在我们在实现国际象棋本身时遇到了错误。 我们在函数的第一个 const 以及 App.jsx 的导出中得到错误
我们的 GitHub 存储库:Chedu
App.jsx
import React, useEffect, useState from "react";
import "./App.css";
import gameSubject, initGame, resetGame from "./Game";
import Board from "./Board";
function App()
const [board, setBoard] = useState([]); //get Error here
const [isGameOver, setIsGameOver] = useState();
const [result, setResult] = useState();
const [turn, setTurn] = useState();
useEffect(() =>
initGame();
const subscribe = gameSubject.subscribe((game) =>
setBoard(game.board);
setIsGameOver(game.isGameOver);
setResult(game.result);
setTurn(game.turn);
);
return () => subscribe.unsubscribe();
, []);
return (
<div className="container">
isGameOver && (
<h2 className="vertical-text">
GAME OVER
<button onClick=resetGame>
<span className="vertical-text"> NEW GAME</span>
</button>
</h2>
)
<div className="board-container">
<Board board=board turn=turn />
</div>
result && <p className="vertical-text">result</p>
</div>
);
export default App(); //Error Anonymous Function
在 Index.js 中,我们正在渲染函数并将其导出。
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import DndProvider from "react-dnd";
import html5Backend from "react-dnd-html5-backend";
export default ReactDOM.render(
<React.StrictMode>
<DndProvider backend=HTML5Backend>
<App />
</DndProvider>
</React.StrictMode>,
document.getElementById("root")
);
serviceWorker.unregister();
最后我们要在 ChessBoardPage 中渲染 index.js
import React, useState from "react";
import
StyleSheet,
Text,
View,
Image,
TouchableOpacity,
Dimensions,
Switch,
from "react-native"; //components
import ReactDOM from "react-dom";
import cheduLogo from "../Pictures/Logo.png";
import loginPictureBlack from "../Pictures/login.png";
import loginPictureWhite from "../Pictures/login_white.png";
import registerPictureBlack from "../Pictures/register.png";
import registerPictureWhite from "../Pictures/register_white.png";
import userPictureBlack from "../Pictures/user.png";
import userPictureWhite from "../Pictures/user_white.png";
import ChessGame from "./ChessBoard/index";
const windowWidth = Dimensions.get("window").width;
const windowHeight = Dimensions.get("window").height;
const width = Dimensions.get("window");
const x = 100;
const y = 200;
export default class TempPage extends React.Component
state =
switchValue: false,
backgroundColor: "white",
SwitchLogin: loginPictureBlack,
SwitchRegister: registerPictureBlack,
SwitchUser: userPictureBlack,
SunMoon: "☀️",
ShadowBackgroundColor: "white",
;
handleSwitchBackground = () =>
[...]
;
render()
let backgroundColor = this.state;
return (
<View
style=
windowWidth,
windowHeight,
backgroundColor: this.state.backgroundColor,
>
[...]
/*Content*/
<View stlye= flex: 1 >
<ChessGame />
</View>
</View>
);
[...]
【问题讨论】:
小错误export default App
不是 export default App()
- 不要调用函数
【参考方案1】:
有时我们在使用匿名函数时会遇到问题。因为匿名函数没有被分配一个标识符(通过 const/let/var),所以只要这个函数组件不可避免地再次被渲染,它们就不是持久的。这会导致 javascript 在每次重新渲染此组件时分配新内存,而不是在使用“命名函数”时仅分配一次内存 考虑重构你的代码如下
import React, useEffect, useState from "react";
import "./App.css";
import gameSubject, initGame, resetGame from "./Game";
import Board from "./Board";
const App = () =>
const [board, setBoard] = useState([]); //get Error here
const [isGameOver, setIsGameOver] = useState();
const [result, setResult] = useState();
const [turn, setTurn] = useState();
useEffect(() =>
initGame();
const subscribe = gameSubject.subscribe((game) =>
setBoard(game.board);
setIsGameOver(game.isGameOver);
setResult(game.result);
setTurn(game.turn);
);
return () => subscribe.unsubscribe();
, []);
return (
<div className="container">
isGameOver && (
<h2 className="vertical-text">
GAME OVER
<button onClick=resetGame>
<span className="vertical-text"> NEW GAME</span>
</button>
</h2>
)
<div className="board-container">
<Board board=board turn=turn />
</div>
result && <p className="vertical-text">result</p>
</div>
);
;
export default App;
我不确定你为什么在 react native 中使用 HTML 标签,这在App.jsx
中尚不支持。您应该返回 <View/>
标签而不是 div。
【讨论】:
以上是关于React Native 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用的主要内容,如果未能解决你的问题,请参考以下文章
React - 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用
React + Antd + Rollup 组件库“错误:无效的钩子调用。钩子只能在函数组件的主体内部调用”
React 17:错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用
react-native 和 yarn 工作区的“钩子只能在函数组件的主体内调用”错误