在If语句中反应setState

时间:2020-09-01 03:45:04

标签: javascript reactjs setstate

我正在使用React开发一个国际象棋游戏,我试图编写一个函数来计算选择某个棋子时应突出显示的方块。我将游戏作为一个组件,将每个国际象棋棋子作为第二个组件,单击该象棋组件中的按钮会从游戏组件中调用一个函数。

仅当所选的部分是正确的颜色时,我才想突出显示适当的正方形,因此我在handleClick()函数的if语句中进行了setState调用。在阅读Issue with setState() in if statement之后,我移动了条件语句,使handleClick函数仅链接到正确颜色的片段。

现在的问题是状态会根据需要进行更改,但是由于某些原因,组件不会重新呈现以反映该更改。有人可以让我知道如何解决这个问题吗?这是我处理点击的代码:


handleClick(num){
    this.setState(prevState => {
        return {
            gameBoard: prevState.gameBoard,
            turn: prevState.turn,
            selected: num
        }
    })
}

这是我创建木板的代码:

<div>
    {
        this.state.gameBoard.map((object)=>
            <div className = "board-row"> {object.map((object2) => 
                <Piece key={object2.at} turn = {this.state.turn} selected = {object2.selected} piece = {object2.piece} identifier = {object2.at} onClick = {() => this.handleClick(object2.at)} color = {(object2.at+Math.floor(object2.at/8))%2 === 0?"white":"black"} />)} 
            </div>
        )
    }
</div>

2 个答案:

答案 0 :(得分:1)

尝试:

handleClick(num){
    this.setState(prevState => {
        return {
                ...prevState,
                selected: num
            };
    })
}

答案 1 :(得分:0)

这里的问题主要是依赖问题。您的渲染基于状态的游戏板字段,该字段未被修改。因此,该组件不会重新渲染,因为它不知道有其他依赖项(已选择)。

我建议的最简单,最干净的方法是,将地图函数简单地移动到具有适当依赖项的useCallback(或useMemo,两者都应该工作)内部,然后在呈现方法中使用它。

const foobar = useCallback( () => this.state.gameBoard.map((object)=>
            <div className = "board-row"> {object.map((object2) => 
                <Piece key={object2.at} turn = {this.state.turn} selected = {object2.selected} piece = {object2.piece} identifier = {object2.at} onClick = {() => this.handleClick(object2.at)} color = {(object2.at+Math.floor(object2.at/8))%2 === 0?"white":"black"} />)} 
            </div>
        )
, [this.state] ) 

render (
  <div>
    {foobar()} 
  </div>
)