使用 React,想修复 useEffect has a missing dependency 错误
Using React, want to fix useEffect has a missing dependency error
出于某种原因,我似乎无法理解这个错误;
我已经研究过它,回调,包括 useEffect
中的代码,但它对我不起作用(或者我做错了)。
代码如下:
import React, { useEffect, useState } from "react";
import "../css/main.css";
import Node from "./node";
const Pathfinder = () => {
const START_NODE_ROW = 10;
const START_NODE_COL = 15;
const FINISH_NODE_ROW = 10;
const FINISH_NODE_COL = 35;
useEffect(() => {
getGrid();
}, []);
const [grid, setGrid] = useState([]);
const getGrid = () => {
setGrid(getInitGrid());
};
const getInitGrid = () => {
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
};
};
return (
<main id="Pathfinder">
{grid.map((row, rowIdx) => {
return (
<div key={rowIdx}>
{row.map((node, nodeIdx) => {
const { row, col, isFinish, isStart } = node;
return (
<Node
key={nodeIdx}
col={col}
isFinish={isFinish}
isStart={isStart}
row={row}
></Node>
);
})}
</div>
);
})}
</main>
);
};
export default Pathfinder;
我基本上是在制作一个节点组件网格;
我必须使用 useEffect
因为我试图只使用箭头函数和钩子,而不使用 类 / react 组件,这就是为什么我不能使用像 componentWillMount
这样的东西。
您需要传递使用的对象,在您的情况下是 getGrid
函数到 useEffect
挂钩以删除警告消息。
就像下面这样:
useEffect(() => {
getGrid();
}, [getGrid]);
T.J. Crowder 的额外建议是 useCallback
用于 getGrid
。您可以按以下方式进行操作:
const getGrid = useCallback(() => {
setGrid(getInitGrid());
}, [getInitGrid]);
在此处进一步阅读:
您需要在代码中对 getInitGrid
执行相同的操作。
希望对您有所帮助!
Pathfinder
中的大部分内容都是静态的,应该移到它的模块之外;这也将对处理您遇到的 useEffect
问题产生影响。所有 START_NODE_ROW
等常量、getInitGrid
和 createNode
都是静态的,不需要每次都重新创建它们。我还将 getGrid
包装在 useCallback
中,并可能稍微重新排序 以便事物仅在定义后使用,但这主要是为了人类 reader,不是 compiler/JavaScript 引擎:
import React, { useEffect, useState } from "react";
import "../css/main.css";
import Node from "./node";
const START_NODE_ROW = 10;
const START_NODE_COL = 15;
const FINISH_NODE_ROW = 10;
const FINISH_NODE_COL = 35;
const getInitGrid = () => {
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 [grid, setGrid] = useState([]);
const getGrid = useCallback(() => {
setGrid(getInitGrid());
}, []);
useEffect(() => {
getGrid();
}, []);
return (
<main id="Pathfinder">
{grid.map((row, rowIdx) => {
return (
<div key={rowIdx}>
{row.map((node, nodeIdx) => {
const { row, col, isFinish, isStart } = node;
return (
<Node
key={nodeIdx}
col={col}
isFinish={isFinish}
isStart={isStart}
row={row}
></Node>
);
})}
</div>
);
})}
</main>
);
};
export default Pathfinder;
另外,getGrid
很小,只用了一次。对我来说,不值得把它分解成自己的功能:
import React, { useEffect, useState } from "react";
import "../css/main.css";
import Node from "./node";
const START_NODE_ROW = 10;
const START_NODE_COL = 15;
const FINISH_NODE_ROW = 10;
const FINISH_NODE_COL = 35;
const getInitGrid = () => {
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 [grid, setGrid] = useState([]);
useEffect(() => {
setGrid(getInitGrid());
}, []);
return (
<main id="Pathfinder">
{grid.map((row, rowIdx) => {
return (
<div key={rowIdx}>
{row.map((node, nodeIdx) => {
const { row, col, isFinish, isStart } = node;
return (
<Node
key={nodeIdx}
col={col}
isFinish={isFinish}
isStart={isStart}
row={row}
></Node>
);
})}
</div>
);
})}
</main>
);
};
export default Pathfinder;
(您不必将 setGrid
或 getInitGrid
声明为依赖项,因为第一个是来自 React 的状态 setter 函数,即 guaranteed to be stable,并且第二个定义在 Pathfinder
之外。)
如 TJ 所述,将函数 getInitGrid
和 createNode
移到组件外部是最好的做法。按照您现在的方式,函数将在每次渲染时重新定义,这不是必需的,因为它们不直接绑定到您的组件状态。
此外,useState
挂钩可以使用 lazy intitial state 这意味着您可以为初始状态参数传递一个函数,并且根本不需要 useEffect 挂钩。
这是我最后得到的结果:
import React, { useState } from "react";
import "../css/main.css";
import Node from "./node";
const START_NODE_ROW = 10;
const START_NODE_COL = 15;
const FINISH_NODE_ROW = 10;
const FINISH_NODE_COL = 35;
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 getInitGrid = () => {
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 Pathfinder = () => {
const [grid, setGrid] = useState(getInitGrid);
return (
<main id="Pathfinder">
{grid.map((row, rowIdx) => {
return (
<div key={rowIdx}>
{row.map((node, nodeIdx) => {
const { row, col, isFinish, isStart } = node;
return (
<Node
key={nodeIdx}
col={col}
isFinish={isFinish}
isStart={isStart}
row={row}
></Node>
);
})}
</div>
);
})}
</main>
);
};
export default Pathfinder;
出于某种原因,我似乎无法理解这个错误;
我已经研究过它,回调,包括 useEffect
中的代码,但它对我不起作用(或者我做错了)。
代码如下:
import React, { useEffect, useState } from "react";
import "../css/main.css";
import Node from "./node";
const Pathfinder = () => {
const START_NODE_ROW = 10;
const START_NODE_COL = 15;
const FINISH_NODE_ROW = 10;
const FINISH_NODE_COL = 35;
useEffect(() => {
getGrid();
}, []);
const [grid, setGrid] = useState([]);
const getGrid = () => {
setGrid(getInitGrid());
};
const getInitGrid = () => {
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
};
};
return (
<main id="Pathfinder">
{grid.map((row, rowIdx) => {
return (
<div key={rowIdx}>
{row.map((node, nodeIdx) => {
const { row, col, isFinish, isStart } = node;
return (
<Node
key={nodeIdx}
col={col}
isFinish={isFinish}
isStart={isStart}
row={row}
></Node>
);
})}
</div>
);
})}
</main>
);
};
export default Pathfinder;
我基本上是在制作一个节点组件网格;
我必须使用 useEffect
因为我试图只使用箭头函数和钩子,而不使用 类 / react 组件,这就是为什么我不能使用像 componentWillMount
这样的东西。
您需要传递使用的对象,在您的情况下是 getGrid
函数到 useEffect
挂钩以删除警告消息。
就像下面这样:
useEffect(() => {
getGrid();
}, [getGrid]);
T.J. Crowder 的额外建议是 useCallback
用于 getGrid
。您可以按以下方式进行操作:
const getGrid = useCallback(() => {
setGrid(getInitGrid());
}, [getInitGrid]);
在此处进一步阅读:
您需要在代码中对 getInitGrid
执行相同的操作。
希望对您有所帮助!
Pathfinder
中的大部分内容都是静态的,应该移到它的模块之外;这也将对处理您遇到的 useEffect
问题产生影响。所有 START_NODE_ROW
等常量、getInitGrid
和 createNode
都是静态的,不需要每次都重新创建它们。我还将 getGrid
包装在 useCallback
中,并可能稍微重新排序 以便事物仅在定义后使用,但这主要是为了人类 reader,不是 compiler/JavaScript 引擎:
import React, { useEffect, useState } from "react";
import "../css/main.css";
import Node from "./node";
const START_NODE_ROW = 10;
const START_NODE_COL = 15;
const FINISH_NODE_ROW = 10;
const FINISH_NODE_COL = 35;
const getInitGrid = () => {
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 [grid, setGrid] = useState([]);
const getGrid = useCallback(() => {
setGrid(getInitGrid());
}, []);
useEffect(() => {
getGrid();
}, []);
return (
<main id="Pathfinder">
{grid.map((row, rowIdx) => {
return (
<div key={rowIdx}>
{row.map((node, nodeIdx) => {
const { row, col, isFinish, isStart } = node;
return (
<Node
key={nodeIdx}
col={col}
isFinish={isFinish}
isStart={isStart}
row={row}
></Node>
);
})}
</div>
);
})}
</main>
);
};
export default Pathfinder;
另外,getGrid
很小,只用了一次。对我来说,不值得把它分解成自己的功能:
import React, { useEffect, useState } from "react";
import "../css/main.css";
import Node from "./node";
const START_NODE_ROW = 10;
const START_NODE_COL = 15;
const FINISH_NODE_ROW = 10;
const FINISH_NODE_COL = 35;
const getInitGrid = () => {
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 [grid, setGrid] = useState([]);
useEffect(() => {
setGrid(getInitGrid());
}, []);
return (
<main id="Pathfinder">
{grid.map((row, rowIdx) => {
return (
<div key={rowIdx}>
{row.map((node, nodeIdx) => {
const { row, col, isFinish, isStart } = node;
return (
<Node
key={nodeIdx}
col={col}
isFinish={isFinish}
isStart={isStart}
row={row}
></Node>
);
})}
</div>
);
})}
</main>
);
};
export default Pathfinder;
(您不必将 setGrid
或 getInitGrid
声明为依赖项,因为第一个是来自 React 的状态 setter 函数,即 guaranteed to be stable,并且第二个定义在 Pathfinder
之外。)
如 TJ 所述,将函数 getInitGrid
和 createNode
移到组件外部是最好的做法。按照您现在的方式,函数将在每次渲染时重新定义,这不是必需的,因为它们不直接绑定到您的组件状态。
此外,useState
挂钩可以使用 lazy intitial state 这意味着您可以为初始状态参数传递一个函数,并且根本不需要 useEffect 挂钩。
这是我最后得到的结果:
import React, { useState } from "react";
import "../css/main.css";
import Node from "./node";
const START_NODE_ROW = 10;
const START_NODE_COL = 15;
const FINISH_NODE_ROW = 10;
const FINISH_NODE_COL = 35;
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 getInitGrid = () => {
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 Pathfinder = () => {
const [grid, setGrid] = useState(getInitGrid);
return (
<main id="Pathfinder">
{grid.map((row, rowIdx) => {
return (
<div key={rowIdx}>
{row.map((node, nodeIdx) => {
const { row, col, isFinish, isStart } = node;
return (
<Node
key={nodeIdx}
col={col}
isFinish={isFinish}
isStart={isStart}
row={row}
></Node>
);
})}
</div>
);
})}
</main>
);
};
export default Pathfinder;