简体   繁体   English

React useCallback linting 错误缺少依赖项

[英]React useCallback linting error missing dependency

I am using a custom hook useInstantSearch in my component.我在我的组件中使用自定义挂钩useInstantSearch

When I wrap it in useCallback to I get the following error:当我将它包装在useCallback中时,我收到以下错误:

React Hook useCallback received a function whose dependencies are unknown. Pass an inline function instead.

This is the code:这是代码:

  const [searchTerm, setSearchTerm] = useState<string>(searchQuery);
  const handleDebouncedSearch = useCallback(
    useInstantSearch(searchTerm, (search, cancelTrigger, searchStillValid) => {
      console.log('instant search', search);
    }),
    []
  );

  useEffect((): void => {
    handleDebouncedSearch(searchTerm);
  }, [searchTerm, handleDebouncedSearch]);

So effectively to send the updated search term to a child component for display only then the parent handles the debouncing of the search when that term changes.如此有效地将更新的搜索词发送到子组件进行显示,然后父组件在该词更改时处理搜索的去抖动。

search, cancelTrigger, searchStillValid

Are not part of the parent component, they are part of useInstantSearch .不是父组件的一部分,它们是useInstantSearch的一部分。

Is this a warning I can ignore?这是我可以忽略的警告吗?

import { useEffect, useRef } from 'react';
import { CancelTrigger } from '../../../ars/api/api.cancel';

const DELAY_SEARCH_MS = 300;

interface InstantSearchOnChange {
  (search: string, cancelTrigger: CancelTrigger, resultStillValid: { (): boolean }): void;
}

/**
 * Helper to delay request until user stop typing (300ms), support deprecated requests (cancel and helper to not update the state), or unmounted component.
 */
export default function useInstantSearch(initialSearch: string, onChange: InstantSearchOnChange): { (value: string): void } {
    
  const search = useRef<string>(initialSearch);
  const requests = useRef<CancelTrigger[]>([]);

  const mounted = useRef<boolean>(true);

  useEffect(() => {
    return (): void => {
      mounted.current = false;
    };
  }, []);

  return value => {
    search.current = value;

    setTimeout(() => {
      if (search.current === value) {
        requests.current = requests.current.filter(r => !r.cancel());

        const trigger = new CancelTrigger();
        requests.current.push(trigger);

        onChange(value, trigger, () => search.current === value && mounted.current);
      }
    }, DELAY_SEARCH_MS);
  };
}

Since you're using some external function, you can simply ignore the message:由于您使用的是一些外部 function,您可以简单地忽略该消息:

useCallback(
  useInstantSearch(...)
, []) // eslint-disable-line react-hooks/exhaustive-deps

However, you should be using it like:但是,您应该像这样使用它:

  const [searchTerm, setSearchTerm] = useState<string>(searchQuery);
  const handleDebouncedSearch = useCallback(() => { // -> this
    useInstantSearch(searchTerm, (search, cancelTrigger, searchStillValid) => {
      console.log('instant search', search);
    })
  }, [searchTerm]); // eslint-disable-line react-hooks/exhaustive-deps

Eslint comment is required here because, you're using callback inside useInstantSearch as there's no way to inject them as dependency.此处需要 Eslint 注释,因为您在 useInstantSearch 中使用回调,因为无法将它们作为依赖项注入。

You can ignore it if you don't mind the stale closures you can do it that way:如果您不介意陈旧的关闭,您可以忽略它,您可以这样做:

 const { useRef, useCallback, useEffect } = React; const DELAY_SEARCH_MS = 300; const later = (value, time) => new Promise((resolve) => setTimeout(() => resolve(value), time) ); /** * Helper to delay request until user stop typing (300ms), support deprecated requests (cancel and helper to not update the state), or unmounted component. */ function useInstantSearch(onChange) { const timeout = useRef(); const mounted = useRef(true); useEffect(() => { return () => { mounted.current = false; }; }, []); return useCallback( (value) => { clearTimeout(timeout.current); //cancel other timeout.current = setTimeout(() => { const current = timeout.current; onChange( value, () => //comparing timeout.current with current // async function may not be the last to resolve // this is important when you want to set state based // on an async result that is triggered on user input // user types "a" and then "b" if 2 async searches start // "a" and "ab" and "a" is so slow it will resolve after "ab" // then state result will be set for "ab" first and then with "a" // causing UI to be out of sync because user searched for "ab" // but results for "a" are shown timeout.current === current && mounted.current ); }, DELAY_SEARCH_MS); }, [onChange] ); } const App = () => { const handler1 = useCallback( (value) => console.log('handler1:', value), [] ); const handler2 = useCallback( (value) => console.log('handler2:', value), [] ); const handler3 = useCallback((value, shouldResolve) => { console.log('starting async with:', value); return later( value, value.length === 1? 1000: 800 ).then( (resolve) => shouldResolve() &&//you can opt not to set state here console.log('resolved with', resolve) ); }, []); const debounced1 = useInstantSearch(handler1); const debounced2 = useInstantSearch(handler2); const debounced3 = useInstantSearch(handler3); [1, 2, 3].forEach( (num) => setTimeout(() => { debounced1(num); debounced2(num * 2); }, 100) //lower than the 300 of debounce ); //both callbacks will be called but "a" resolves after "ab" since // "ab" was the last to be requested it will be the only one that logs // resolved with setTimeout(() => debounced3('a'), 500); setTimeout(() => debounced3('ab'), 1500); return 'hello world (check console)'; }; ReactDOM.render(<App />, document.getElementById('root'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>

There may be a solution to your problem but without knowing what useInstantSearch is it's impossible to provide one.您的问题可能有解决方案,但在不知道useInstantSearch是什么的情况下,不可能提供解决方案。

My guess is that you should use useCallback inside useInstantSearch but since that code is missing from your question I can only guess.我的猜测是您应该在useInstantSearch useCallback由于您的问题中缺少该代码,因此我只能猜测。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 反应 useEffect 和 useCallback linting 错误 - 缺少依赖项 - React useEffect and useCallback linting error - missing dependency React Hook useEffect/useCallback 缺少依赖项 - React Hook useEffect/useCallback has a missing dependency 在 useEffect 上使用方法有困难,缺少依赖项和 useCallback 错误? - Having difficulty using a method on useEffect, missing dependency and useCallback error? 反应:useCallback - useCallback 与空依赖数组 VS 根本不使用 useCallback - React: useCallback - useCallback with empty dependency array VS not using useCallback at all Cube.js React Hook React.useCallback 缺少一个依赖项:'pivotConfig'。 + - Cube.js React Hook React.useCallback has a missing dependency: 'pivotConfig'. + 如何确定 React.useCallback 的依赖列表? - How to decide the dependency list for React.useCallback? React Hook useEffect 错误缺少依赖项 - React Hook useEffect Error missing dependency React usecallback 不遵守由子函数引起的依赖项更改 - React usecallback not honoring dependency change caused by child function React - useCallback 在 renderProps 函数上抛出错误 - React - useCallback throwing error on renderProps function 反应 useCallback 钩子,没有收到更新的依赖 state 值 - React useCallback hook, not receiving updated dependency state value
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM