【问题标题】:Why isn't my array copying without reference in React?为什么我的数组在 React 中没有引用复制?
【发布时间】:2020-04-25 10:46:28
【问题描述】:

我正在制作一个 Web 应用程序来使用 React 可视化寻路算法。我目前已经实现了 Dijkstra 算法。但是,当我将初始网格数组的副本传递给我的寻路算法时,原始数组会被修改。

import React, { useState } from "react";
import Node from "./Node";
import dijkstras from "../algorithms/dijkstras";

const START_NODE_ROW = 10;
const START_NODE_COL = 15;
const FINISH_NODE_ROW = 10;
const FINISH_NODE_COL = 35;

const getGrid = () => {
  const grid = [];
  for (let row = 0; row < 20; row++) {
    const currentRow = [];
    for (let col = 0; col < 50; 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 Pathfinder = () => {
  const initialGrid = getGrid();
  const [grid, setGrid] = useState([...initialGrid]);

  const animatePath = visitedNodesInOrder => {
    for (let i = 0; i < visitedNodesInOrder.length; i++) {
      setTimeout(() => {
        const node = visitedNodesInOrder[i];
        const newGrid = grid.slice();
        const newNode = {
          ...node,
          isVisited: true
        };
        newGrid[node.row][node.col] = newNode;
        setGrid(newGrid);
      }, 100 * i);
    }
  };

  const visualizeDijkstras = () => {
    const tempGrid = [...grid];
    const startNode = tempGrid[START_NODE_ROW][START_NODE_COL];
    const finishNode = tempGrid[FINISH_NODE_ROW][FINISH_NODE_COL];
    const visitedNodesInOrder = dijkstras(tempGrid, startNode, finishNode);
    animatePath(visitedNodesInOrder);
  };

  return (
    <>
      <button onClick={() => visualizeDijkstras()}></button>
      <div className="grid">
        {grid.map((row, rowIndex) => {
          return (
            <div key={rowIndex}>
              {row.map((node, nodeIndex) => {
                const { isStart, isFinish, isVisited } = node;
                return (
                  <Node
                    key={nodeIndex}
                    isStart={isStart}
                    isFinish={isFinish}
                    isVisited={isVisited}
                  />
                );
              })}
            </div>
          );
        })}
      </div>
    </>
  );
};

export default Pathfinder;

目前所有节点都设置为在 animatePath() 方法的第一次迭代时访问,因为初始网格数组中的节点已经被 dijkstras 方法标记为已访问。尽管我将初始数组复制到临时数组并将其传递给路径查找方法。

【问题讨论】:

  • 您还需要复制所有嵌套数组。 tempGrid = 新数组,tempGrid[START_NODE_ROW] = 对原始嵌套数组的引用。

标签: javascript arrays reactjs jsx


【解决方案1】:

正如我在评论中所述,问题是您复制的数组具有指向其原始引用的嵌套数组。因此,当您创建像 ...grid 这样的新数组时,您正在使用对原始子数组的引用来构建新数组。

解决方案也是创建新的子数组。

如果数组只有 2 深,你可以这样做:

const tempGrid = [...grid.map.(subArray => [...subArray])];

【讨论】:

    猜你喜欢
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 2018-03-27
    • 2020-08-15
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多