繁体   English   中英

如何调用 useEffect 在特定的 state 更改时重新渲染

[英]How can I call useEffect to re-render upon a particular state change

我需要下面的第一个 useEffect 在更改网格 state 时重新渲染。 具体来说,当我将网格对象的一个值重新分配为 true 时,一旦为 changeWall function 内的grid注册了 state 的更改,我需要包含initializeGrid()的 useEffect 重新渲染。 我需要此更改以立即重新渲染该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;

问题

grid state 是常量,因此尝试grid = new Array(X); 将在initializeGrid中引发错误。 也许您打算声明一个新变量来初始化/更新 state 。

const grid = new Array(X);

回答

使用第二块 state 表示“墙”已更改。 初始 state 为true将允许initializeGrid function 在初始组件安装渲染上运行。

const [wallChanged, setWallChanged] = useState(true);

useEffect(() => {
  if (wallChanged) {
    setWallChanged(false);
    initializeGrid();
  }
}, [wallChanged]);

在处理程序中设置墙更改 state 以触发重新初始化。

function changeWall(e) {
  const { id } = e.target;
  grid[id.y][id.x].isWall = true; // *
  setWallChanged(true);
}

*注意:注意grid[id.y][id.x].isWall = true; 是 state 突变。 在没有太多其他上下文的情况下,虽然我不能确定这是否是一个实际问题,但它绝对是代码异味。

实际上,由于initializeGrid完全重置了网格 state,这可能不是问题,实际上, grid[id.y][id.x].isWall = true; 使用wallChanged state“标志”,行可能并非完全不需要。

一个更简单的解决方案可能只是直接在处理程序中调用initializeGrid 没有额外的 state 和grid state 已更新,组件重新渲染至少比我以前的解决方案早 1 个渲染周期。

function changeWall(e) {
  initializeGrid();
}

暂无
暂无

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

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