Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么在我用React钩子调用setState之前,我的状态一直在更新?如何修复禁用的鼠标指针?_Javascript_Reactjs - Fatal编程技术网

Javascript 为什么在我用React钩子调用setState之前,我的状态一直在更新?如何修复禁用的鼠标指针?

Javascript 为什么在我用React钩子调用setState之前,我的状态一直在更新?如何修复禁用的鼠标指针?,javascript,reactjs,Javascript,Reactjs,目前,我在重建dijkstras寻路可视化工具时遇到两个问题 我的代码沙盒: 如果单击/单击并拖动到轴网上,可以创建阻止路径的墙节点。但是,如果你点击并拖动几个节点,释放鼠标按钮并点击并拖动你结束的同一个节点,鼠标指针不知何故被禁用,并且没有注意到onMouseUp事件。结果:仍然单击鼠标-->因此即使未按下鼠标,您仍然可以在MouseOver上创建墙 以前,通过getElementById.classname添加一个类来为算法访问的节点设置动画。但是我实际上想通过传递属于状态的isvisted

目前,我在重建dijkstras寻路可视化工具时遇到两个问题

我的代码沙盒:

  • 如果单击/单击并拖动到轴网上,可以创建阻止路径的墙节点。但是,如果你点击并拖动几个节点,释放鼠标按钮并点击并拖动你结束的同一个节点,鼠标指针不知何故被禁用,并且没有注意到onMouseUp事件。结果:仍然单击鼠标-->因此即使未按下鼠标,您仍然可以在MouseOver上创建墙

  • 以前,通过
    getElementById.classname
    添加一个类来为算法访问的节点设置动画。但是我实际上想通过传递属于状态的
    isvisted
    属性来更新子组件中的类。但是我不明白为什么在调用
    setState
    之前,我的
    在我的状态中被访问了
    ,或者我如何正确地执行它。当前,所有已访问的节点在返回白色之前都会立即设置动画,就好像它们未被访问一样

  • 包装器组件:

    import React, { useState, useEffect, useCallback, useRef } from "react";
    import Node from "../Node/Node";
    
    import "./PathfindingVisualizer.css";
    
    import { dijkstra, getNodesInShortestPathOrder } from "../algorithms/dijkstras";
    
    const START_NODE_ROW = 0;
    const START_NODE_COL = 0;
    const FINISH_NODE_ROW = 0;
    const FINISH_NODE_COL = 3;
    
    const TOTAL_ROWS = 5;
    const TOTAL_COLS = 10;
    
    const PathfindingVisualizer = () => {
      const [nodeGrid, setNodeGrid] = useState({
        grid: []
      });
    
      const mouseIsPressed = useRef(false);
    
      useEffect(() => {
        const grid1 = getInitialGrid();
        setNodeGrid({ ...nodeGrid, grid: grid1 });
      }, []);
    
      const handleMouseDown = useCallback((row, col) => {
        //console.log(newGrid);
        setNodeGrid(prevGrid => ({
          grid: getNewGridWithWallToggled(prevGrid.grid, row, col)
        }));
        mouseIsPressed.current = true;
        //console.log(nodeGrid);
      }, []);
    
      // function handleMouseDown(row, col) {
      //   const newGrid = getNewGridWithWallToggled(nodeGrid.grid, row, col);
      //  console.log(newGrid);
      //   setNodeGrid({...nodeGrid, nodeGrid[row][col]= newGrid});
      // }
    
      const handleMouseEnter = useCallback((row, col) => {
        //console.log(mouseIsPressed);
        if (mouseIsPressed.current) {
          setNodeGrid(prevNodeGrid => ({
            ...prevNodeGrid,
            grid: getNewGridWithWallToggled(prevNodeGrid.grid, row, col)
          }));
        }
      }, []);
    
      const handleMouseUp = useCallback(() => {
        mouseIsPressed.current = false;
      }, []);
    
      // const animateDijkstra = (visitedNodesInOrder, nodesInShortestPathOrder) => {
      //   for (let i = 0; i <= visitedNodesInOrder.length; i++) {
      //     if (i === visitedNodesInOrder.length) {
      //       setTimeout(() => {
      //         animateShortestPath(nodesInShortestPathOrder);
      //       }, 10 * i);
      //       return;
      //     }
      //     setTimeout(() => {
      //       const node = visitedNodesInOrder[i];
      //       document.getElementById(`node-${node.row}-${node.col}`).className =
      //         "node node-visited";
      //     }, 10 * i);
      //   }
      // };
    
      const animateDijkstra = (visitedNodesInOrder, nodesInShortestPathOrder) => {
        for (let i = 0; i <= visitedNodesInOrder.length; i++) {
          if (i === visitedNodesInOrder.length) {
            setTimeout(() => {
              animateShortestPath(nodesInShortestPathOrder);
            }, 17 * i);
            return;
          }
          setTimeout(() => {
            const node = visitedNodesInOrder[i];
            console.log("node", node);
            console.log("state", nodeGrid);
            console.log(
              "before setNode",
              nodeGrid.grid[node.row][node.col].isVisited
            );
            setNodeGrid(prevNodeGrid => ({
              ...prevNodeGrid,
              grid: getNewGridWithVisited(prevNodeGrid.grid, node.row, node.col)
              //   //grid: node
            }));
            console.log(
              "after setNode;",
              nodeGrid.grid[node.row][node.col].isVisited
            );
          }, 17 * i);
        }
      };
    
      const animateShortestPath = nodesInShortestPathOrder => {
        for (let i = 0; i < nodesInShortestPathOrder.length; i++) {
          setTimeout(() => {
            const node = nodesInShortestPathOrder[i];
            document.getElementById(`node-${node.row}-${node.col}`).className =
              "node node-shortest-path";
          }, 50 * i);
        }
      };
    
      const visualizeDijkstra = () => {
        const grid = nodeGrid.grid;
        console.log(grid);
        const startNode = grid[START_NODE_ROW][START_NODE_COL];
        const finishNode = grid[FINISH_NODE_ROW][FINISH_NODE_COL];
        const visitedNodesInOrder = dijkstra(grid, startNode, finishNode);
        const nodesInShortestPathOrder = getNodesInShortestPathOrder(finishNode);
        animateDijkstra(visitedNodesInOrder, nodesInShortestPathOrder);
      };
    
      //console.log(nodeGrid.grid);
      //console.log(visualizeDijkstra());
      return (
        <>
          <button onClick={visualizeDijkstra}>
            Visualize Dijkstra´s Algorithm
          </button>
          <div className="grid">
            test
            {nodeGrid.grid.map((row, rowIdx) => {
              return (
                <div className="row" key={rowIdx}>
                  {row.map((node, nodeIdx) => {
                    const { row, col, isStart, isFinish, isWall, isVisited } = node;
                    return (
                      <Node
                        key={nodeIdx}
                        col={col}
                        row={row}
                        isStart={isStart}
                        isFinish={isFinish}
                        isWall={isWall}
                        isVisited={isVisited}
                        onMouseDown={handleMouseDown}
                        onMouseEnter={handleMouseEnter}
                        onMouseUp={handleMouseUp}
                      />
                    );
                  })}
                </div>
              );
            })}
          </div>
        </>
      );
    };
    
    export default PathfindingVisualizer;
    
    //----------------------------------------------------------
    
    const getInitialGrid = () => {
      const grid = [];
      for (let row = 0; row < TOTAL_ROWS; row++) {
        const currentRow = [];
        for (let col = 0; col < TOTAL_COLS; col++) {
          currentRow.push(createNode(col, row));
        }
        grid.push(currentRow);
      }
      return grid;
    };
    
    const createNode = (col, row) => {
      return {
        col,
        row,
        isStart: row === START_NODE_ROW && col === START_NODE_COL,
        isFinish: row === FINISH_NODE_ROW && col === FINISH_NODE_COL,
        distance: Infinity,
        isVisited: false,
        isWall: false,
        previousNode: null
      };
    };
    
    const getNewGridWithWallToggled = (grid, row, col) => {
      const newGrid = grid.slice();
      const node = newGrid[row][col];
      const newNode = {
        ...node,
        isWall: !node.isWall
      };
      newGrid[row][col] = newNode;
      return newGrid;
    };
    
    const getNewGridWithVisited = (grid, row, col) => {
      const newGrid = grid.slice();
      const node1 = newGrid[row][col];
      const newNode = {
        ...node1,
        isVisited: true
        //isVisited: !node1.isVisited
      };
      //console.log(newNode);
      newGrid[row][col] = newNode;
      return newGrid;
    };
    
    import React from "react";
    
    import "./Node.css";
    import { useCountRenders } from "../Node/useCountRenders";
    
    const Node = React.memo(
      ({
        col,
        isFinish,
        isStart,
        isWall,
        onMouseDown,
        onMouseEnter,
        onMouseUp,
        row,
        isVisited
      }) => {
        //console.log("props: col, isWall, row;", col, isWall, row);
        const extraClassName = isFinish
          ? "node-finish"
          : isStart
          ? "node-start"
          : isWall
          ? "node-wall"
          : isVisited
          ? 'node-visited'
          : "";
    
        useCountRenders();
    
        console.log("node rerendered: row:", row, "col:", col);
        return (
          <div
            id={`node-${row}-${col}`}
            className={`node ${extraClassName}`}
            onMouseDown={() => onMouseDown(row, col)}
            onMouseEnter={() => onMouseEnter(row, col)}
            onMouseUp={() => onMouseUp()}
          />
        );
      }
    );
    
    export default Node;
    
    import React,{useState,useffect,useCallback,useRef}来自“React”;
    从“./Node/Node”导入节点;
    导入“/PathfindingVisualizer.css”;
    从“./algorithms/dijkstras”导入{dijkstra,getNodesInShortestPathOrder};
    常量开始节点行=0;
    const START_NODE_COL=0;
    const FINISH\u NODE\u ROW=0;
    const FINISH_NODE_COL=3;
    const TOTAL_ROWS=5;
    const TOTAL_COLS=10;
    常量路径查找可视化工具=()=>{
    const[nodeGrid,setNodeGrid]=useState({
    网格:[]
    });
    const mouseIsPressed=useRef(false);
    useffect(()=>{
    const grid1=getInitialGrid();
    setNodeGrid({…nodeGrid,grid:grid1});
    }, []);
    const handleMouseDown=useCallback((行,列)=>{
    //console.log(newGrid);
    setNodeGrid(prevGrid=>({
    网格:getNewGridWithWallToggled(prevGrid.grid,行,列)
    }));
    mouseIsPressed.current=true;
    //console.log(nodeGrid);
    }, []);
    //功能手柄向下(行、列){
    //const newGrid=getnewgridwithwalltogled(nodeGrid.grid,row,col);
    //console.log(newGrid);
    //setNodeGrid({…nodeGrid,nodeGrid[row][col]=newGrid});
    // }
    常量HandleMouseCenter=useCallback((行,列)=>{
    //console.log(鼠标按下);
    如果(鼠标按下。当前){
    setNodeGrid(prevNodeGrid=>({
    …prevNodeGrid,
    网格:getNewGridWithWallToggled(prevNodeGrid.grid,行,列)
    }));
    }
    }, []);
    const handleMouseUp=useCallback(()=>{
    mouseIsPressed.current=false;
    }, []);
    //常量animateDijkstra=(已访问NodesNorder、nodesInShortestPathOrder)=>{
    //for(设i=0;i{
    //animateShortestPath(nodesinshortestpath顺序);
    //(a)10*i);
    //返回;
    //     }
    //设置超时(()=>{
    //const node=visitedNodesInOrder[i];
    //document.getElementById(`node-${node.row}-${node.col}`)。className=
    //“已访问的节点”;
    //(a)10*i);
    //   }
    // };
    常量animateDijkstra=(已访问NodesNorder、nodesInShortestPathOrder)=>{
    for(设i=0;i{
    animateShortestPath(nodesinshortestpath顺序);
    },17*i);
    返回;
    }
    设置超时(()=>{
    const node=visitedNodesInOrder[i];
    console.log(“节点”,node);
    日志(“状态”,nodeGrid);
    console.log(
    “在setNode之前”,
    nodeGrid.grid[node.row][node.col].isvisted
    );
    setNodeGrid(prevNodeGrid=>({
    …prevNodeGrid,
    网格:getNewGridWithVisited(prevNodeGrid.grid、node.row、node.col)
    ////网格:节点
    }));
    console.log(
    “在setNode之后;”,
    nodeGrid.grid[node.row][node.col].isvisted
    );
    },17*i);
    }
    };
    常量animateShortestPath=nodesinshortestpath=>{
    for(设i=0;i{
    const node=nodesInShortestPathOrder[i];
    document.getElementById(`node-${node.row}-${node.col}`)。className=
    “节点最短路径”;
    },50*i);
    }
    };
    常量dijkstra=()=>{
    const grid=nodeGrid.grid;
    控制台日志(网格);
    const startNode=grid[START_NODE_ROW][START_NODE_COL];
    const finishNode=grid[FINISH_NODE_ROW][FINISH_NODE_COL];
    const visitedNodesInoder=dijkstra(网格、开始节点、完成节点);
    const nodesInShortestPathOrder=getNodesInShortestPathOrder(finishNode);
    animateDijkstra(访问NodesNorder、NodesInshortstPathOrder);
    };
    //日志(nodeGrid.grid);
    //log(dijkstra());
    返回(
    可视化Dijkstra算法
    测试
    {nodeGrid.grid.map((row,rowIdx)=>{
    返回(
    {row.map((node,nodeIdx)=>{
    const{row,col,isStart,isFinish,isWall,isvisitored}=node;
    返回(
    );
    })}
    );
    })}
    );
    };
    导出默认路径查找可视化工具;
    //----------------------------------------------------------
    常量getInitialGrid=()=>{
    常量网格=[];
    for(让行=0;行<总行数;行++){
    const currentRow=[];
    for(设col=0;col{
    返回{
    上校,
    一行
    isStart:row===START\u NODE\u row&&col===START\u NODE\u col,
    isFinish:row===FINISH\u NODE\u row&&col===FINISH\u NODE\u col,
    距离:无限,
    伊斯曼:错,
    伊斯沃尔:错,
    previousNode:空
    };
    };
    const getNewGridWithWallToggled=(网格、行、列)=>{
    const newGrid=grid.slice()
    
      const handleMouseEnter = useCallback((row, col) => {
        //console.log(mouseIsPressed);
        if (mouseIsPressed.current) {
          setNodeGrid(prevNodeGrid => ({
            ...prevNodeGrid,
            grid: getNewGridWithWallToggled(prevNodeGrid.grid, row, col)
          }));
        }
      }, []); <= empty dependency array
    
    import _ from "lodash";
    
    //--------
    
     const visualizeDijkstra = () => {
    
        const grid = _.cloneDeep(nodeGrid.grid);
    
        // other code
      }