useEffect 中缺少依赖项的 eslint 警告 [英] eslint warning for missing dependency in useEffect

查看:234
本文介绍了useEffect 中缺少依赖项的 eslint 警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个可搜索的下拉菜单并收到以下 eslint 警告:

<块引用>

React Hook useEffect 缺少依赖项:filterDropDown"和restoreDropDown".包括它们或删除依赖项数组.

import React, { useState, useEffect, useCallback } from "react";const SearchableDropDown2 = () =>{const [searchText, setSearchText] = useState("");const [dropdownOptions, setDropdownOptions] = useState([反应",角",Vue",jQuery",Nextjs",]);const [copyOfdropdownOptions, setCopyOfDropdownOptions] = useState([...下拉选项,]);const [isExpand, setIsExpand] = useState(false);useEffect(() => {searchText.length >0 ?filterDropDown() : restoreDropDown();}, [搜索文本]);const onClickHandler = (e) =>{setSearchText(e.target.dataset.myoptions);setIsExpand(false);};const onSearchDropDown = () =>setIsExpand(true);const closeDropDownHandler = () =>setIsExpand(false);const filterDropDown = useCallback(() => {constfilteredDropdown = dropdownOptions.filter((_) =>_.toLowerCase().includes(searchText.toLowerCase()));setDropdownOptions([...filteredDropdown]);}, [下拉选项]);const restoreDropDown = () =>{if (dropdownOptions.length !== copyOfdropdownOptions.length) {setDropdownOptions([...copyOfdropdownOptions]);}};const onSearchHandler = (e) =>setSearchText(e.target.value.trim());返回 (<div style={styles.mainContainer}><输入类型=搜索"值={搜索文本}onClick={onSearchDropDown}onChange={onSearchHandler}风格={styles.search}占位符=搜索"/><button disabled={!isExpand} onClick={closeDropDownHandler}>——

(<跨度onClick={onClickHandler}style={styles.dropdownOptions}数据我的选项={_}值={_}>{_}</span>))}

);};常量样式 = {主容器:{填充:1vh 1vw",宽度:28vw",边距:自动自动",},下拉容器:{宽度:25vw",背景:灰色",高度:10vh",溢出:滚动",},下拉选项:{显示:块",高度:2vh",颜色:白色",填充:0.2vh 0.5vw",光标:指针",},搜索: {宽度:25vw",},};

我尝试将 filterDropDown 包装在 useCallback 中,但随后可搜索下拉列表停止工作.

以下是包含 useCallback 的更改:

const filterDropDown = useCallback(() => {constfilteredDropdown = dropdownOptions.filter((_) =>_.toLowerCase().includes(searchText.toLowerCase()));setDropdownOptions([...filteredDropdown]);}, [dropdownOptions, searchText]);

解决方案

我的建议是在您要实现的环境中根本不要使用 useEffect.

import React, {useState} from 'react';const SearchableDropDown = () =>{const [searchText, setSearchText] = useState('');const dropdownOptions = ['React','Angular','Vue','jQuery','Nextjs'];const [isExpand, setIsExpand] = useState(false);const onClickHandler = e =>{setSearchText(e.target.dataset.myoptions);setIsExpand(false);}const onSearchDropDown = () =>setIsExpand(true);const closeDropDownHandler = () =>setIsExpand(false);const onSearchHandler = e =>setSearchText(e.target.value.trim());返回 (<div style={styles.mainContainer}><输入类型=搜索"值={搜索文本}onClick={onSearchDropDown}onChange={onSearchHandler}风格={styles.search}占位符=搜索"/><button disabled={!isExpand} onClick={closeDropDownHandler}>——

opt.toLowerCase().includes(searchText.toLowerCase())).map((option, idx) =><span key={idx} onClick={onClickHandler} style={styles.dropdownOptions} data-myoptions={option} value={option}>{选项}</span>)}

);};常量样式 = {主容器:{填充:'1vh 1vw',宽度:'28vw',边距:'自动自动'},下拉容器:{宽度:'25vw',背景:'灰色',高度:'10vh',溢出:'滚动'},下拉选项:{显示:'块',高度:'2vh',白颜色',填充:'0.2vh 0.5vw',光标:'指针',},搜索: {宽度:'25vw',},};

只需过滤 dropDownOptions,然后再将它们映射到 span 元素.

此外,如果 dropDownOptions 的列表会发生变化,则使用 setState 否则只需将其保留为简单列表.如果 dropDownOptions 来自 api 调用,则在 useEffect 钩子中使用 setState.

I am making a searchable Dropdown and getting following eslint warning:

React Hook useEffect has missing dependencies: 'filterDropDown' and 'restoreDropDown'. Either include them or remove the dependency array.

import React, { useState, useEffect, useCallback } from "react";
const SearchableDropDown2 = () => {
  const [searchText, setSearchText] = useState("");
  const [dropdownOptions, setDropdownOptions] = useState([
    "React",
    "Angular",
    "Vue",
    "jQuery",
    "Nextjs",
  ]);
  const [copyOfdropdownOptions, setCopyOfDropdownOptions] = useState([
    ...dropdownOptions,
  ]);
  const [isExpand, setIsExpand] = useState(false);

  useEffect(() => {
    searchText.length > 0 ? filterDropDown() : restoreDropDown();
  }, [searchText]);

  const onClickHandler = (e) => {
    setSearchText(e.target.dataset.myoptions);
    setIsExpand(false);
  };

  const onSearchDropDown = () => setIsExpand(true);

  const closeDropDownHandler = () => setIsExpand(false);

  const filterDropDown = useCallback(() => {
    const filteredDropdown = dropdownOptions.filter((_) =>
      _.toLowerCase().includes(searchText.toLowerCase())
    );
    setDropdownOptions([...filteredDropdown]);
  }, [dropdownOptions]);

  const restoreDropDown = () => {
    if (dropdownOptions.length !== copyOfdropdownOptions.length) {
      setDropdownOptions([...copyOfdropdownOptions]);
    }
  };

  const onSearchHandler = (e) => setSearchText(e.target.value.trim());
  return (
    <div style={styles.mainContainer}>
      <input
        type="search"
        value={searchText}
        onClick={onSearchDropDown}
        onChange={onSearchHandler}
        style={styles.search}
        placeholder="search"
      />
      <button disabled={!isExpand} onClick={closeDropDownHandler}>
        -
      </button>
      <div
        style={
          isExpand
            ? styles.dropdownContainer
            : {
                ...styles.dropdownContainer,
                height: "0vh",
              }
        }
      >
        {dropdownOptions.map((_, idx) => (
          <span
            onClick={onClickHandler}
            style={styles.dropdownOptions}
            data-myoptions={_}
            value={_}
          >
            {_}
          </span>
        ))}
      </div>
    </div>
  );
};

const styles = {
  mainContainer: {
    padding: "1vh 1vw",
    width: "28vw",
    margin: "auto auto",
  },
  dropdownContainer: {
    width: "25vw",
    background: "grey",
    height: "10vh",
    overflow: "scroll",
  },
  dropdownOptions: {
    display: "block",
    height: "2vh",
    color: "white",
    padding: "0.2vh 0.5vw",
    cursor: "pointer",
  },
  search: {
    width: "25vw",
  },
};

I tried wrapping the filterDropDown in useCallback but then the searchable dropdown stopped working.

Following are the changes incorporating useCallback:

const filterDropDown = useCallback(() => {
  const filteredDropdown = dropdownOptions.filter((_) =>
    _.toLowerCase().includes(searchText.toLowerCase())
  );
  setDropdownOptions([...filteredDropdown]);
}, [dropdownOptions, searchText]);

解决方案

My suggestion would be to not use useEffect at all in the context of what you are achieving.

import React, {useState} from 'react';

const SearchableDropDown = () => {
    const [searchText, setSearchText] = useState('');
    const dropdownOptions = ['React','Angular','Vue','jQuery','Nextjs'];
    const [isExpand, setIsExpand] = useState(false);


    const onClickHandler = e =>  {
        setSearchText(e.target.dataset.myoptions);
        setIsExpand(false);
    }

    const onSearchDropDown = () => setIsExpand(true);
    const closeDropDownHandler = () => setIsExpand(false);
    const onSearchHandler = e => setSearchText(e.target.value.trim());

    return (
        <div style={styles.mainContainer}>
            <input
                type="search"
                value={searchText}
                onClick={onSearchDropDown}
                onChange={onSearchHandler}
                style={styles.search}
                placeholder="search"
            />
            <button disabled={!isExpand} onClick={closeDropDownHandler}>
                -
            </button>
            <div
                style={
                    isExpand
                        ? styles.dropdownContainer
                        : {
                                ...styles.dropdownContainer,
                                height: '0vh',
                            }
                }
            >
                {dropdownOptions
                    .filter(opt => opt.toLowerCase().includes(searchText.toLowerCase()))
                    .map((option, idx) =>
                        <span key={idx} onClick={onClickHandler} style={styles.dropdownOptions} data-myoptions={option} value={option}>
                            {option}
                        </span>
                    )}
            </div>
        </div>
    );
};

const styles = {
    mainContainer: {
        padding: '1vh 1vw',
        width: '28vw',
        margin: 'auto auto'
    },
    dropdownContainer: {
        width: '25vw',
        background: 'grey',
        height: '10vh',
        overflow: 'scroll'
    },
    dropdownOptions: {
        display: 'block',
        height: '2vh',
        color: 'white',
        padding: '0.2vh 0.5vw',
        cursor: 'pointer',
    },
    search: {
        width: '25vw',
    },
};

Just filter the dropDownOptions before mapping them to the span elements.

also, if the list of dropDownOptions is ever going to change then use setState else just leave it as a simple list. If dropDownOptions comes from an api call, then use setState within the useEffect hook.

这篇关于useEffect 中缺少依赖项的 eslint 警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆