【问题标题】:Warning: Cannot update a component (`App`) while rendering a different component (`History`)警告:在渲染不同的组件(`History`)时无法更新组件(`App`)
【发布时间】:2021-06-03 04:07:00
【问题描述】:

我实际上正在构建井字游戏。但这个错误实际上并没有让我更新历史记录。当我在skillshare.com上关注教程时,我做了和他一样的事情。但仍然出现错误。我是 React 的初学者。我使用 nano-react npm 项目来创建这个项目。 这是 App.js:

import React , {useState} from "react";
import Board from "./components/Board"
import History from "./components/History"
import {calculateWinner} from './support'
import StatusMessage from './components/StatusMessage'
import './styles/root.scss'

const NEW_GAME = [
  {
    board: Array(9).fill(null),
    isXNext : true
  }
]
const App = () => {

  const [history, setHistory] = useState(NEW_GAME);
  const [currentMove, setCurrentMove] = useState(0);

  const current = history[currentMove];

  const {winner , winningSquare} = calculateWinner(current.board);
  
  const clickHandleFunction = (position) => {
      if (current.board[position] || winner) {
          return;
      }

      setHistory((prev) => {
        const last = prev[prev.length-1];

          const newBoard =  last.board.map((square, pos) => {
              if (pos === position) {
                  return last.isXNext ? 'X' : '0';
              }
              return square;
          });
          return prev.concat({board: newBoard, isXNext : !last.isXNext})
      });

      setCurrentMove(prev => prev +1);
  };

  const moveTo = (move) => {
    setCurrentMove(move);
  }

  const onNewGame  = () => {
    setHistory(NEW_GAME);
    setCurrentMove(0);
  }

  return(
    <div className="app">
      <h1>TIC TAC TOE</h1>
      <StatusMessage winner ={winner} current ={current}/>
      <Board board = {current.board} clickHandleFunction = {clickHandleFunction} winningSquare = {winningSquare}/>
      <button type="button" onClick = {onNewGame}>Start New Game</button>
      <History history={history} moveTo = {moveTo} currentMove = {currentMove} />
    </div>
  )
}
export default App;

这是我的 History.js:

import React from 'react.'

function History({history, moveTo, currentMove}) {
    return (
        <ul>
            {
                history.map((_, move) => {
                    return( <li key={move}> <button style={{
                        fontWeight: move === currentMove ? 'bold' : 'normal'
                    }} type="button" onClick = {moveTo(move)} > 
                        {move === 0 ? 'Go to game start!': `Gove to move #${move}`} </button> </li> );
                })
            }   
        </ul>
    )
}

export default History

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

问题出在History.js:

onClick={moveTo(move)}

您需要在 onClick 属性中提供一个函数。相反,您调用moveTo 函数并将其返回值作为onClick 属性传递。

因此,每当 React 渲染 History 组件时,它也会无意中调用 moveTo 函数,该函数会触发 App 组件中的更新。这就是错误所说的 - 渲染组件时无法更新另一个组件。

要解决此问题,请将 moveTo(move) 更改为 () =&gt; moveTo(move)。现在您将一个函数传递给onClick,当用户单击时,该函数将调用moveTo 函数。工作沙箱:https://codesandbox.io/s/practical-frog-tcyxm?file=/src/components/History.js

【讨论】:

    【解决方案2】:

    React Navigation 中,将 setParamssetOptions 移动到类组件中的方法 componentDidMount() 或函数组件中的 useEffects() 挂钩中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-29
      • 2021-07-05
      • 2022-09-24
      • 2020-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      相关资源
      最近更新 更多