【问题标题】:ReactJS: Update UI when state changesReactJS:状态更改时更新 UI
【发布时间】:2019-12-02 15:14:54
【问题描述】:

我是 ReactJS 的新手,我正在尝试创建一个数独求解器。

当我更新状态时,我希望 UI 也更新,因此用户可以看到算法在做什么。

使用我当前的代码,UI 仅在最后更新并立即填满整个数独板。

我尝试在很多地方使用setTimeout(),但没有成功。

这是我的 React 类:

import React from 'react';
import './App.sass';
import Button from '@material-ui/core/Button';

export default class App extends React.Component {
  constructor() {
    super();
    this.state = { board: [
        ["5","3",".",".","7",".",".",".","."],
        ["6",".",".","1","9","5",".",".","."],
        [".","9","8",".",".",".",".","6","."],
        ["8",".",".",".","6",".",".",".","3"],
        ["4",".",".","8",".","3",".",".","1"],
        ["7",".",".",".","2",".",".",".","6"],
        [".","6",".",".",".",".","2","8","."],
        [".",".",".","4","1","9",".",".","5"],
        [".",".",".",".","8",".",".","7","9"]
      ]
    };
  }

  createTable = () => {
    let table = [];

    for(let row = 0; row < this.state.board.length; row++) {
      let children = [];

      for(let col = 0; col < this.state.board[0].length; col++) {
        children.push(<td>{this.state.board[row][col]}</td>)
      }
      table.push(<tr>{children}</tr>)
    }
    return table
  }

  solveSudoku = board => {
    for(let row = 0; row < board.length; row++) {
        for(let col = 0; col < board[row].length; col++) {
          if(board[row][col] === '.') {
            for(let num = 1; num <= 9; num++) {
              // Check if valid
              if(this.isValid(board, row, col, num)) {
                board[row][col] = num.toString();
                this.setState(board);

                if(this.solveSudoku(board)) {
                  this.setState(board);
                  return true;
                } else {
                  board[row][col] = '.';
                  this.setState(board);
                }
              }
            }
            return false;
          }
        }
      }
      return true;
  }

  isValid = (board, row, col, num) => {
    for(let i = 0; i < 9; i++) {
      // Check row
      if(parseInt(board[row][i]) === num) {
        return false;
      // Check column
      } else if(parseInt(board[i][col]) === num) {
        return false;
      // Check Subgrid
      } else if(parseInt(board[3 * (Math.floor(row / 3)) + Math.floor(i / 3)][3 * (Math.floor(col / 3)) + i % 3]) === num) {
        return false;
      }
    }
    return true
  }

  render() {
    return (
      <div className="App">
        <table>
          <tbody>
            {this.createTable()}
          </tbody>
        </table>
        <Button variant="contained" color="primary" onClick={() => this.solveSudoku(this.state.board)}>Solve</Button>
      </div>
    );
  }
}

【问题讨论】:

  • 我还没有阅读你所有的代码,但你可能应该打电话给this.setState({ board })而不是this.setState(board)
  • 最简单的解决方法是在更新函数入口处设置状态为空。
  • @dev_junwen 我更新了我的代码,但还是不行
  • 我已经复制了您的代码并进行了测试,它似乎工作正常
  • @dev_junwen UI 是否一次更新每个数字,因此用户可以看到算法在做什么?

标签: javascript reactjs state settimeout


【解决方案1】:

UI 会在状态更改或道具更改时自动重新呈现。 看来您设置的状态不正确。

setState 应该包含一个新的 state 实例,它是一个对象。 所以应该是这样的:this.setState({newState});

【讨论】:

  • 你的状态也应该是不可变的,所以你需要将你的板复制到一个新的对象中,而不是改变 this.state.board。 const newBoard = {...board} 然后你可以改变 newBoard 并调用 this.setState({board: newBoard})
猜你喜欢
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 2021-12-29
相关资源
最近更新 更多