简体   繁体   English

React state 更新...但我不知道为什么

[英]React state updates...but I don't know why

I'm making a tic - tac - toe game using React, and I am confused as to how my state is updating.我正在使用 React 制作井字游戏,我对 state 的更新方式感到困惑。 I'm using hooks.我正在使用钩子。

I have a state array which contains 9 objects, each with properties 'num' (from 0 to 8) and with an empty string for 'val'.我有一个 state 数组,其中包含 9 个对象,每个对象都有属性“num”(从 0 到 8)和一个空字符串表示“val”。 When a square has been clicked, depending on who is active or not, I wanted the value of the square to have been update to "X" or "O".单击正方形后,根据谁处于活动状态,我希望正方形的值已更新为“X”或“O”。

For this I presumed that I would have had to use the spread operator and update my state with my newly updated array, but I'm not, I'm using square brackets to select the square I want, and assigning it a new value depending on the player.为此,我假设我必须使用扩展运算符并用我新更新的数组更新我的 state,但我没有,我使用方括号将 select 用作我想要的方块,并为其分配一个新值,具体取决于在播放器上。

I'm just wondering how, I don't understand how my state updates, you can see in my code where I've commented out the use of the spread operator upon realising that it seems unnecessary.我只是想知道如何,我不明白我的 state 是如何更新的,你可以在我的代码中看到我在意识到似乎没有必要时注释掉了扩展运算符的使用。 The logic is in my clickHandler.逻辑在我的 clickHandler 中。 Any explanation or resource would be really handy for me to understand this, Thanks.任何解释或资源对我理解这一点都非常方便,谢谢。 App.js应用程序.js

import React from 'react';
import { useState } from 'react'
import Square from './components/Square'
// possible winning rows
// switch between player 1 and 2
// reset button
const App = () => {
  const [playerX, setPlayerX] = useState([])
  const [playerO, setPlayerO] = useState([])
  // false = playerX
  const [activePlayer, setActivePlayer] = useState(false)
  const [square, setSquare] = useState([
    { num: 0, val: '' },
    { num: 1, val: '' },
    { num: 2, val: '' },
    { num: 3, val: '' },
    { num: 4, val: '' },
    { num: 5, val: '' },
    { num: 6, val: '' },
    { num: 7, val: '' },
    { num: 8, val: '' }
  ])

  const clickHandler = (squareItem) => {
    // square clicked
    // let newSquares = [...square]

    const squareUpdate = square[squareItem.num]
   // check active player
    if(activePlayer) { 

   // push square num to player array
    setPlayerO([...playerO, squareItem.num ])

   // change square value
    squareUpdate.val = "O"

   // update state array with changed 
   // setSquare([...newSquares])

    setActivePlayer(!activePlayer)
    }else {
   // add square num to player array
     setPlayerX([...playerX, squareItem.num ])

   // change square value
    squareUpdate.val = "X"

   // update state array with changed 
   // setSquare([...newSquares])

    setActivePlayer(!activePlayer)
    }
  }
  return (
    <div id="game">
      <h1>Tic - Tac - Toe</h1>
      <div id="grid">
        {square.map((squareItem, index) => {
          return <Square 
          activePlayer={activePlayer}
          squareItem={squareItem} 
          clickHandler={clickHandler}
          />
        })}
      </div>
    </div>
  )
}
export default App

Square.js广场.js

import React from 'react'
const Square = ({ squareItem, clickHandler }) => {
  return (
    <div 
      onClick={() => clickHandler(squareItem)} 
      className="square" 
      value={squareItem.value}>
      {squareItem.num}
    </div>
  )
}
export default Square

Square is any array and referenced by instance and not value. Square 是任何数组,由实例而不是值引用。 Because you call another setState (setActivePlayer) react rerenders the component with the values of square changed but its still the same object reference and therefore has the updated values.因为您调用了另一个 setState (setActivePlayer),react 重新渲染了square值已更改的组件,但它仍然是相同的 object 引用,因此具有更新的值。

If you remove the other setState calls and only set the object values it wont rerender.如果您删除其他 setState 调用并仅设置 object 值,它将不会重新呈现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM