从反应钩开始。我试图在窗口中添加一个事件侦听器,在单击'Enter‘时调用一个函数。该函数将执行几个API请求,并使用状态变量传递appropiate查询字符串,然后更新数据状态。
然而,我有一个问题--这是我遇到的错误:
React useEffect缺少一个依赖项:'getData‘。要么包含它,要么删除依赖数组react/react。
这是代码:
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钩子(位于第66行)的依赖项在每次呈现时都发生变化。要解决这个问题,请将'getData‘定义包装到自己的useCallback() Hook中
然后,我尝试定义一个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函数。此外,我必须向函数中添加参数,而不是直接使用搜索和位置变量。
这是正确的方法还是我错过了什么?
发布于 2019-05-23 20:54:46
这是正确的方法,这似乎是很多麻烦,但有很多正在进行。为了使它更容易和更可重用,您可以将许多代码抽象到它自己的钩子中。
这是我用的钩子
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]);
};然后,组件中的代码将如下所示:
const getData = () => {
console.log("Use these vars directly", search, location);
};
const getDataMemo = useCallback(getData, [search, location]);
useKeyDown("Enter", getDataMemo);https://stackoverflow.com/questions/56272888
复制相似问题