React Hooks入门。我试图在单击“ Enter”后调用函数的窗口上添加事件侦听器。此函数将执行一些API请求,并使用状态变量来传递适当的查询字符串并随后更新数据状态。
但是我有问题-这是我得到的错误:
反应挂钩useEffect缺少依赖项:'getData'。要么包含它,要么删除依赖项数组react-hooks / exhaustive-deps
这是代码:
const [data, setData] = useState([]);
const [search, setSearch] = useState('');
const [location, setLocation] = useState('');
useEffect(() => {
function handleKeyPress(e) {
if (e.key === "Enter") {
getData();
}
}
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [])
function getData() {
setData([]);
fetch(`${URL}/api-1?search=${search}&location=${location}`)
.then(res => res.json())
.then(data => setData(cur => [...cur, ...data]));
fetch(`${URL}/api-2?search=${search}&location=${location}`)
.then(res => res.json())
.then(data => setData(cur => [...cur, ...data]));
}
就像错误消息说的那样,它在依赖项数组中缺少作为依赖项的getData,我尝试添加它,但又得到了另一条错误消息:
'getData'函数使useEffect Hook的依赖关系(在第66行)在每个渲染器上都改变。要解决此问题,请将“ getData”定义包装到其自己的useCallback()挂钩中
然后我尝试定义一个useCallback挂钩,并按如下所示重构useEffect和函数调用:
function getData(searchArg, locationArg) {
setData([]);
fetch(`${URL}/api-1?search=${searchArg}&location=${locationArg}`)
.then(res => res.json())
.then(data => setData(cur => [...cur, ...data]));
fetch(`${URL}/api-2?search=${searchArg}&location=${locationArg}`)
.then(res => res.json())
.then(data => setData(cur => [...cur, ...data]));
}
const getDataMemo = useCallback(() => {
getData(search, location);
}, [search, location]);
useEffect(() => {
function handleKeyPress(e) {
if (e.key === "Enter") {
getDataMemo();
}
}
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [getDataMemo])
现在我没有收到任何警告,但似乎只是添加一个“ Enter”事件侦听器以启动1个功能而感到很麻烦。另外,我不得不在函数中添加参数,而不仅仅是直接使用搜索和位置变量。
这是正确的方法还是我错过了什么?
答案 0 :(得分:2)
这是正确的方法,确实看起来很麻烦,但仍有很多事情要做。为了使它更容易和更可重用,您可以将很多代码抽象到自己的钩子中。
这是我使用的钩子
event.currentTarget.dataset.columnIndex
您组件中的代码如下:
const useKeyDown = (key, handler) => {
// Create a ref that stores handler
const savedHandler = useRef();
// Make sure we always have the latest handler.
useEffect(() => {
savedHandler.current = handler;
}, [handler]);
useEffect(() => {
const handleKeyDown = event => {
if (event.key === key) {
savedHandler.current();
}
};
window.addEventListener("keydown", handleKeyDown);
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
}, [key]);
};