簡體   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