useEffect 中缺少依赖项的 eslint 警告 [英] eslint warning for missing dependency in useEffect
问题描述
我正在制作一个可搜索的下拉菜单并收到以下 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屋!