useEffect 中的一个简单事件侦听器导致多个警告
A simple event listener in useEffect causing several warnings
React Hooks 入门。我正在尝试在 window 上添加一个事件侦听器,它在单击 'Enter' 时调用一个函数。此函数将执行一些 API 请求并使用状态变量传递适当的查询字符串并随后更新数据状态。
但是我有一个问题 - 这是我得到的错误:
React Hook 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() 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 个函数很麻烦。此外,我必须向我的函数添加参数,而不是直接使用搜索和位置变量。
这是正确的方法还是我错过了什么?
这是正确的方法,它看起来确实很麻烦,但有很多事情要做。为了使它更容易和更多 re-usable 您可以将大量代码抽象到它自己的钩子中。
这是我用的钩子
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);
React Hooks 入门。我正在尝试在 window 上添加一个事件侦听器,它在单击 'Enter' 时调用一个函数。此函数将执行一些 API 请求并使用状态变量传递适当的查询字符串并随后更新数据状态。
但是我有一个问题 - 这是我得到的错误:
React Hook 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() 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 个函数很麻烦。此外,我必须向我的函数添加参数,而不是直接使用搜索和位置变量。
这是正确的方法还是我错过了什么?
这是正确的方法,它看起来确实很麻烦,但有很多事情要做。为了使它更容易和更多 re-usable 您可以将大量代码抽象到它自己的钩子中。
这是我用的钩子
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);