首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >useEffect中导致多个警告的简单事件侦听器

useEffect中导致多个警告的简单事件侦听器
EN

Stack Overflow用户
提问于 2019-05-23 10:07:47
回答 1查看 3.1K关注 0票数 0

从反应钩开始。我试图在窗口中添加一个事件侦听器,在单击'Enter‘时调用一个函数。该函数将执行几个API请求,并使用状态变量传递appropiate查询字符串,然后更新数据状态。

然而,我有一个问题--这是我遇到的错误:

React useEffect缺少一个依赖项:'getData‘。要么包含它,要么删除依赖数组react/react

这是代码:

代码语言:javascript
复制
 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和函数调用:

代码语言:javascript
复制
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函数。此外,我必须向函数中添加参数,而不是直接使用搜索和位置变量。

这是正确的方法还是我错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-23 20:54:46

这是正确的方法,这似乎是很多麻烦,但有很多正在进行。为了使它更容易和更可重用,您可以将许多代码抽象到它自己的钩子中。

这是我用的钩子

代码语言:javascript
复制
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]);
};

然后,组件中的代码将如下所示:

代码语言:javascript
复制
const getData = () => {
  console.log("Use these vars directly", search, location);
};
const getDataMemo = useCallback(getData, [search, location]);
useKeyDown("Enter", getDataMemo);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56272888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档