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

Javascript useEffect中的一个简单事件侦听器导致多个警告,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,开始使用React钩子。我正在尝试在窗口中添加一个事件侦听器,该窗口在单击“Enter”时调用函数。此函数将执行一些API请求,并使用状态变量传递适当的查询字符串,然后更新数据状态 但是我有一个问题-这是我得到的错误: React Hook useEffect缺少依赖项:“getData”。包括它或删除依赖项数组react hooks/deps 代码如下: const [data, setData] = useState([]); const [search, setSearch] = us

开始使用React钩子。我正在尝试在窗口中添加一个事件侦听器,该窗口在单击“Enter”时调用函数。此函数将执行一些API请求,并使用状态变量传递适当的查询字符串,然后更新数据状态

但是我有一个问题-这是我得到的错误:

React Hook useEffect缺少依赖项:“getData”。包括它或删除依赖项数组react hooks/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挂钩(第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个函数似乎会有很多麻烦。此外,我必须向函数中添加参数,而不是直接使用搜索和位置变量


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

这是正确的方法,看起来确实有很多麻烦,但还有很多事情要做。为了使它更容易和更可重用,您可以将大量代码抽象到它自己的钩子中

这是我用的钩子

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);

这是正确的方法,看起来确实有很多麻烦,但是还有很多事情要做。为了使它更容易和更可重用,您可以将大量代码抽象到它自己的钩子中

这是我用的钩子

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);