【问题标题】:A simple event listener in useEffect causing several warningsuseEffect 中的一个简单事件侦听器导致多个警告
【发布时间】:2019-10-09 21:22:17
【问题描述】:

React Hooks 入门。我正在尝试在单击“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() 挂钩中

然后我尝试定义一个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 个函数似乎很麻烦。此外,我必须向我的函数添加参数,而不是直接使用搜索和位置变量。

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

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多