[英]How can I call useEffect to re-render upon a particular state change
I need the first useEffect below to re-render upon a change to the grid state.我需要下面的第一个 useEffect 在更改网格 state 时重新渲染。 Specifically, I need the useEffect containing
initializeGrid()
to re-render once a change of state is registered for grid
inside the changeWall function when I reassigned one of the grid object's values to true.具体来说,当我将网格对象的一个值重新分配为 true 时,一旦为 changeWall function 内的
grid
注册了 state 的更改,我需要包含initializeGrid()
的 useEffect 重新渲染。 I need this change to immediately re-render that initializeGrid()
function我需要此更改以立即重新渲染该
initializeGrid()
function
import React, { useState, useEffect } from "react";
const Pathfind = () => {
const [grid, setGrid] = useState(false);
useEffect(() => {
initializeGrid();
}, []);
const initializeGrid = () => {
grid = new Array(X);
for (let i = 0; i < Y; i++) {
grid[i] = new Array(Y);
}
setGrid(grid);
};
let isMouseDown = false;
function changeWall(e) {
let id = e.target.id;
grid[id.y][id.x].isWall = true;
}
useEffect(() => {
document.addEventListener("mousedown", function () {
isMouseDown = true;
document.onmouseup = () => {
isMouseDown = false;
document.removeEventListener("mouseover", changeWall);
};
if (mouseIsDown) {
document.addEventListener("mouseover", changeWall);
}
});
}, []);
};
export default Pathfind;
The grid
state is const, so attempting grid = new Array(X);
grid
state 是常量,因此尝试grid = new Array(X);
will throw an error in initializeGrid
.将在
initializeGrid
中引发错误。 Perhaps you meant to declare a new variable to initialize/update state with.也许您打算声明一个新变量来初始化/更新 state 。
const grid = new Array(X);
Use a second piece of state to indicate a "wall" was changed.使用第二块 state 表示“墙”已更改。 Initial state of
true
will allow the initializeGrid
function to run on the initial component mounting render.初始 state 为
true
将允许initializeGrid
function 在初始组件安装渲染上运行。
const [wallChanged, setWallChanged] = useState(true);
useEffect(() => {
if (wallChanged) {
setWallChanged(false);
initializeGrid();
}
}, [wallChanged]);
Set wall changed state in the handler to trigger re-initialization.在处理程序中设置墙更改 state 以触发重新初始化。
function changeWall(e) {
const { id } = e.target;
grid[id.y][id.x].isWall = true; // *
setWallChanged(true);
}
* Note: Be aware that grid[id.y][id.x].isWall = true;
*注意:注意
grid[id.y][id.x].isWall = true;
is a state mutation.是 state 突变。 Without much other context though I can't say for sure if this is an actual issue, but it is definitely a code smell.
在没有太多其他上下文的情况下,虽然我不能确定这是否是一个实际问题,但它绝对是代码异味。
Actually, since initializeGrid
resets the grid state completely, this is probably not an issue, and really, the grid[id.y][id.x].isWall = true;
实际上,由于
initializeGrid
完全重置了网格 state,这可能不是问题,实际上, grid[id.y][id.x].isWall = true;
line may not be completely unnecessary with the wallChanged
state "flag".使用
wallChanged
state“标志”,行可能并非完全不需要。
A much simpler solution may just be to invoke initializeGrid
directly in the handler.一个更简单的解决方案可能只是直接在处理程序中调用
initializeGrid
。 No extra state and the grid
state is updated and component rerenders at least 1 render cycle earlier than my previous solution.没有额外的 state 和
grid
state 已更新,组件重新渲染至少比我以前的解决方案早 1 个渲染周期。
function changeWall(e) {
initializeGrid();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.