[英]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.