我越来越频繁地以各种形式遇到这种情况:(简化示例)
const searchParameters = useState();
const sorting = useState();
// update searchParameters if the user enters someting
// update sorting if the user clicks on a column in the table
// PROBLEM: I only want to call loadEntries() if sorting changes, but I need searchParameters for it too!
useEffect(
() => loadEntries(sorting, searchParameters),
// eslint-disable-next-line react-hooks/exhaustive-deps
[sorting]
);
react-hooks/exhaustive-deps?
react-hooks/exhaustive-deps
? (本例中为搜索参数)您可以使用
ref
来保存 searchParameters
的当前值,并且由于 ref
本身不会更改(仅 current
属性),您甚至不需要将其声明为依赖项:
const searchParameters = useState();
const sorting = useState();
// init the ref
const searchParametersRef = useRef(searchParameters);
// update the ref
useEffect(() => {
searchParametersRef.current = searchParameters;
});
useEffect(
() => loadEntries(sorting, searchParametersRef.current), // use the ref
[sorting]
);
据我所知,您无法禁用
react-hooks/exhaustive-dep
等特定属性,例如 searchParameters
。 配置仅处理规则。
@OriDrori 的答案可以解决这个问题。
如果需要不基于参考的替代解决方案,可以查看以下帖子。 当然,这是以额外的状态和单独的 useEffect 语句为代价的。
编码亮点
a。用于排序的额外状态
const [prevSorting, setPrevSorting] = useState();
b。两个单独的 useEffect 调用
第一个 useEffect 将为每个渲染调用,但内部逻辑将根据排序状态的变化应用。
第二个 useEffect 将仅在排序状态发生变化时调用,并将同步设置 preSorting 状态。
useEffect(() => {
if (sorting !== prevSorting) {
loadEntries(sorting, searchParameters);
}
});
useEffect(() => {
setPrevSorting(sorting);
}, [sorting]);
代码 - 完整列表:
App.js
import { useState, useEffect } from 'react';
function loadEntries(sorting, searchParameters) {
console.log(`loadEntries executed with : ${sorting},${searchParameters}`);
}
export default function App() {
const [searchParameters, setSearchParameters] = useState('');
const [sorting, setSorting] = useState();
const [prevSorting, setPrevSorting] = useState();
// update searchParameters if the user enters someting
function handleChangeSearchParameters(newValue) {
setSearchParameters(newValue);
}
// update sorting if the user clicks on a column in the table
function handleClickSorting(newValue) {
setSorting(newValue);
}
// PROBLEM: I only want to call loadEntries() if sorting changes, but I need searchParameters for it too!
useEffect(() => {
if (sorting !== prevSorting) {
loadEntries(sorting, searchParameters);
}
});
useEffect(() => {
setPrevSorting(sorting);
}, [sorting]);
return (
<>
<button onClick={() => handleClickSorting(Math.random())}>
Click sorting
</button>
<br />
<label>searchParameters</label>
<br />
<input
value={searchParameters}
onChange={(e) => handleChangeSearchParameters(e.target.value)}
></input>
</>
);
}
试运行
新输入的搜索参数
它没有调用 useEffect 来进行排序的更改,请查看控制台中没有记录任何内容
通过单击按钮更改排序
它确实调用了 useEffect 来进行排序的更改,请查看控制台中记录了一些内容。
搜索参数更改
它没有调用 useEffect 来更改排序,请查看控制台中没有新记录的内容。
通过单击按钮更改排序
它确实调用了 useEffect 来更改排序,请查看控制台中有新记录的内容。