简体   繁体   English

React 中只运行一次的功能组件

[英]Functional components in React that run only once

I was trying to create a grid in React and got really confused when my program gave me different outputs depending on whether I save the file in my editor or refresh the page on the live server.我试图在 React 中创建一个网格,当我的程序根据我将文件保存在编辑器中还是刷新实时服务器上的页面而给我不同的输出时,我感到非常困惑。

Afaik the useEffect() hook runs only once if you pass it an empty array, [] , as the second parameter.如果您将一个空数组[]作为第二个参数传递给它,那么useEffect()钩子只会运行一次。 However, when I run my code:但是,当我运行我的代码时:

  const [grid, setGrid] = useState([]);
  console.log(grid);

  useEffect(() => {
      const grid = [];
      for (let row = 0; row < 15; row++) {
          const currentRow = [];
          for (let node = 0; node < 40; node++) {
              currentRow.push(createNode(node, row));
          }
          grid.push(currentRow);
      }
      setGrid(grid);
  }, []);

The console logs two (I'm not 100% sure why it console.log twice but alas) arrays with a total of 600 createNode(node, row) objects, which is what I want.控制台记录了两个(我不是 100% 确定为什么它console.log两次但唉)arrays 总共有 600 个createNode(node, row)对象,这就是我想要的。 And if I edit the code and save it also displays this, My problem is that if I refresh the live server the console spits out an empty array, [] , on the first console.log and then it logs the array of 600 objects.如果我编辑代码并保存它也会显示这个,我的问题是,如果我刷新实时服务器,控制台会在第一个console.log上吐出一个空数组[] ,然后记录 600 个对象的数组。

I have other functionality in my program that uses the grid array but I'm pretty sure these break because they are passed an empty array.我的程序中还有其他使用grid数组的功能,但我很确定这些功能会中断,因为它们传递了一个空数组。 At least I get an error "cannot read property 'x' of undefined" when I manually refresh the page compared to when I just save in the editor.与仅在编辑器中保存时相比,当我手动刷新页面时,至少我得到一个错误“无法读取未定义的属性'x'”。

Any help/insight would be greatly appreciated...任何帮助/见解将不胜感激......

EDIT: The grid renders just fine but as soon as I import my logic for Dijkstra's algorithm编辑:网格渲染得很好,但只要我导入 Dijkstra 算法的逻辑

import dijkstra from "./algorithms/dijkstra";

Then I call the function然后我打电话给 function

dijkstra(grid, grid[7][10])

which is only partly implemented but still:这只是部分实施但仍然:

function dijkstra(grid, startNode) {
    const unvisitedNodes = getNodes(grid);
    startNode.distance = 0;
    sortByDistance(unvisitedNodes);
    const closestNode = unvisitedNodes.shift();
    console.log(getNeighbors(closestNode, grid));
}

function sortByDistance(nodes) {
    nodes.sort((nodeA, nodeB) => nodeA.distance - nodeB.distance);
}

function getNodes(grid) {
    const unvisitedNodes = [];
    for (const row of grid) {
        for (const node of row) {
            unvisitedNodes.push(node);
        }
    }
    return unvisitedNodes;
}

function getNeighbors(referenceNode, grid) {
    const neighbors = [];
    const { row, col } = referenceNode;
    if (row > 0) neighbors.push(grid[row + 1][col]);
    if (row < grid.length - 1) neighbors.push(grid[row - 1][col]);
    if (col > 0) neighbors.push(grid[row][col - 1]);
    if (col < grid[0].length - 1) neighbors.push(grid[row][col + 1]);
    return neighbors;
}

export default dijkstra;

yes that's how React works.是的,这就是React的工作原理。 Whenever you refresh your browser the app renders.每当您刷新浏览器时,应用程序就会呈现。 In React render在 React 渲染中

  1. At first, states are initialized (that's why your 1st console log was empty array)首先,状态被初始化(这就是你的第一个控制台日志是空数组的原因)
  2. then DOM prints然后 DOM 打印
  3. then lifecycle methods or hooks are initialized然后初始化生命周期方法或钩子
  4. then DOM again prints with updated state.(that's why you have the objects in 2nd log) the whole process repeats when you reload your browser.然后 DOM 再次使用更新的 state 打印。(这就是为什么您在第二个日志中有对象)当您重新加载浏览器时,整个过程会重复。

[] in useEffect prevents re-run of the hook when you update your states only. useEffect中的[]可防止仅在更新状态时重新运行挂钩。

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

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