【问题标题】:React Native Error: Invalid hook call. Hooks can only be called inside of the body of a function componentReact Native 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用
【发布时间】: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() - 不要调用函数

标签: reactjs react-native react-hooks react-dom react-web


【解决方案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 中尚不支持。您应该返回 &lt;View/&gt; 标签而不是 div。

【讨论】:

    猜你喜欢
    • 2020-11-20
    • 2021-03-30
    • 2020-06-22
    • 2019-09-07
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    相关资源
    最近更新 更多