繁体   English   中英

React setState 不更新 UI

[英]React setState not updating the UI

对于我这个唯一遇到这个问题的人来说,这似乎太奇怪了......但是让我解释一下:

我正在构建一个名为 Game of Life 的 React 应用程序(您可能已经听说过)。 我正在使用一个简单的表单组件,它迭代 Arrays 的数组,基本上创建一个 20 x 20 的字段。 还有一个按钮,可以开始下一次迭代。

加载数据并将数据获取到我的 LandParcel.js,在那里我开始计算下一步工作非常好。 数据甚至加载到 state,但不会更新 UI。 这是为什么?

App.js(应用程序的起点)

import { useState } from 'react';
import './App.css';
import { LandParcel } from './components/core/LandParcel';
import { Form } from './components/ui/Form';


function App() {

  // set the grid with random variables
  const [ grid, setGrid ] = useState(LandParcel.createForm)

  console.log('rerender because grid changed', grid)

  function showGrid(grid) {
    console.log('grid to be handed over to Form = ', grid)
  }

  return (
    <div className="container mt-4">
      <h1 className="text-center" onClick={() => showGrid(grid)}>Game of Life</h1>

      {/* load the grip, pass the states forward */}
      <Form
        grid={ grid }
        setGrid={ setGrid }
      />

    </div>
  );
}

export default App;

然后将数据和 setGrid 转发到这个 Form.jsx:


import { LandParcel } from "../core/LandParcel"

export const Form = ({ grid, setGrid }) => {
    
    // handles the click on the input button
    function handleInput(e) {

        e.preventDefault();
        LandParcel.renderNextStep(grid, setGrid)
    }

    // debugging only
    function giveInfo(status, x, y) {
        console.log(status, x, y);
    }

    return(
        <form className="form">

            <div className="parcelForm">
                {grid.map((row, x) => row.map((col, y) => (
                    <div className={grid[x][y].status ? "alive" : "dead"} onClick={() => giveInfo(grid[x][y], x, y)}/>
                    ))
                )}
            </div>

            <input type="submit" value="Start" className="btn btn-danger btn-block" onClick={handleInput}></input>
          </form>
    )
}

handleInput function 然后调用 LandParcel.js 中的一个方法,该方法在计算后尝试像这样设置 state:


export class LandParcel {

    constructor(status) {
        this.status = status;
    }


    static createForm() {
        const rows = [];
        for (let i = 0; i < 20; i++) {
            rows.push(Array.from(Array(20), () => new LandParcel((Math.random() > 0.9 ? 1 : 0)))); 
        }
        
        return rows;
    }


    static renderNextStep(grid, setGrid) {

        let gridCopy = grid
        
        // Calculating the next step in here

        console.log('updated grid', gridCopy)
        setGrid(gridCopy)
        
    }

    // for debugging only, creates a new grid with all values set to 0
    static setCustomStep() {
        const rows = [];
        for (let i = 0; i < 20; i++) {
            rows.push(Array.from(Array(20), () => new LandParcel(0))); 
        }

        return rows;
    }

}

对我来说奇怪的是,当我使用创建一个所有值都设置为 0 的新网格的辅助函数调用 setGrid(setCustomStep) 时,它会更新 UI - 但如果我调用 setGrid(gridCopy) 则不会。

我确定我遗漏了什么,但我不知道是什么。 非常感谢任何帮助/提示::)

我认为这是因为您正试图通过 gridCopy 变量直接更新 state。

当您将 grid 等同于 gridCopy 时,它仅传递对网格(状态)的引用而不是在 memory 中存储新变量查看本文以获取更多信息

一个解决方案是将网格深度复制到 gridCopy 中,这将在 memory 中创建一个新变量,而不是传递对网格的引用

let gridCopy = [...grid]

暂无
暂无

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

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