【问题标题】:Adding dependency in useEffect hook causes infinite loop在 useEffect 钩子中添加依赖会导致无限循环
【发布时间】:2020-02-26 20:10:13
【问题描述】:

我在搜索栏周围有一个包装器组件,它在每次击键时获取建议,然后在选择建议或用户点击输入/搜索时进行搜索。选择搜索值后,我想将该搜索项保存到本地存储中,以便我可以将其显示为焦点,就像 Google 一样。这是我的组件的 sn-p

export default function App() {
    const [results, resultsLoading, resultsError, setParams] = useFetch();
    const [suggestions, ,suggestionsError, setSuggestionsParams] = useFetch();
    const [showSearchSuggestions, setShowSearchSuggestions] = useState<boolean>(true);
    const [recentSearches, setRecentSearches] = useLocalStorage('recent_searches', []);
    const [searchAttributes, setSearchAttributes] = useState<SearchAtrributesInterface>({
        value: '',
        fetchType: SEARCH_FETCH_TYPES.SUGGESTIONS
    });

    useEffect(() => {
        const getSearchSuggestions = () => setSuggestionsParams(getAutoCompleteURL(searchAttributes.value));
        const getSearchResults = () => {
            setParams(getSearchURL(searchAttributes.value));
            setShowSearchSuggestions(false);
        };

        if (searchAttributes.value) {
            if (searchAttributes.fetchType === SEARCH_FETCH_TYPES.SUGGESTIONS) {
                getSearchSuggestions();
            } else {
                getSearchResults();
                setRecentSearches([searchAttributes.value, ...recentSearches])
            }
        }
    }, [searchAttributes, setParams, setSuggestionsParams]);

    return ( ... );
};

这很好用,但随后我收到了 linting 警告:React Hook useEffect has missing dependencies: 'recentSearches' and 'setRecentSearches'. Either include them or remove the dependency array react-hooks/exhaustive-deps。将这两个添加到依赖数组中后,我陷入了无限循环,因为当然recentSearches 的状态正在设置,导致它重新渲染等等。我想找到一个与添加// eslint-disable-next-line 相反的解决方案,因为我觉得我做的事情确实有问题。有谁知道我可以做些什么来防止无限循环并防止 linter 警告?

【问题讨论】:

  • 不要太在意react-hooks/exhaustive-deps。仅当您想在依赖关系更改时更新值时才合乎逻辑。将其视为建议而非要求。您可能只想做一次事情,并有一个空的 [] 作为依赖项。这也会引发警告,尽管它毫无意义
  • 一种效果会发生很多事情。可能最好将它们分成多种效果。

标签: javascript reactjs react-hooks use-effect


【解决方案1】:

它有两件事。

由于您希望利用现有的状态值来更新相同的状态,您应该使用回调方法

setRecentSearches(prevRececentSearches => ([searchAttributes.value, ...prevRececentSearches]));

此外,当您完全确定没有遗漏任何依赖项时,您可以禁用警告。详情请查看此帖:How to fix missing dependency warning when using useEffect React Hook?

【讨论】:

  • 非常感谢您的建议。是的,我见过一些人说你不应该把 linter 警告看得太认真,但我觉得你总是应该或者他们不会在那里。不过,很高兴知道陪审团不在此列。谢谢!
  • 这个 linter 并不完美,它不知道你想要什么,不想要什么。这里的 Linter 是为了提示您是否错误地遗漏了任何内容,而不是强制它添加所有依赖项
猜你喜欢
  • 2021-09-27
  • 2021-07-25
  • 2021-04-10
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
相关资源
最近更新 更多