React useEffect导致函数运行7次.我正在使用useCallback,但它仍然运行了很多次



带有console.log("running")的updateAddedState函数在页面刷新/初始渲染时运行7次。

我只希望updateAddedState函数在addedItems状态更新时运行一次。

我只在实际的adddeditems状态发生变化时才运行useEffect。我做错了什么?

export const DropdownMultiSelect = ({
data,
placeholder,
updateState,
}: IProps) => {
const [searchTerm, setSearchTerm] = useState<string>("");
const [filteredData, setFilteredData] = useState<IData[]>(data);
const [addedItems, setAddedItems] = useState<IData[]>([]);
const [placeholderValue, setPlaceholderValue] = useState<string>("");
const [inputActive, setInputActive] = useState<boolean>(false);
const onFocus = () => setInputActive(true);
const onBlur = () => {
setInputActive(false);
};
const updateAddedState = useCallback(() => {
console.log("running");

updateState(addedItems);
}, [updateState, addedItems]);
const handleFilter = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearchTerm(e.target.value);
};
const handleFilterData = useCallback(
(searchTerm: string) => {
let newFilter = data.filter((value) => {
return value.name.toLowerCase().includes(searchTerm.toLowerCase());
});
for (let i = 0; i < addedItems.length; i++) {
for (let j = 0; j < newFilter.length; j++) {
if (addedItems[i].id === newFilter[j].id) {
newFilter.splice(j, 1);
}
}
}
setFilteredData(newFilter);
},
[addedItems, data]
);
const addItem = (value: IData) => {
setAddedItems([...addedItems, value]);
setSearchTerm("");
handleFilterData("");
setInputActive(false);
};
const removeItem = (value: IData, e: React.MouseEvent) => {
e.preventDefault();
let newArray: IData[] = [];
for (let i = 0; i < addedItems.length; i++) {
newArray.push(addedItems[i]);
}
for (let i = 0; i < newArray.length; i++) {
if (value.id === newArray[i].id) {
newArray.splice(i, 1);
}
}
setAddedItems(newArray);
setInputActive(true);
};
useEffect(() => {
if (addedItems.length === 1) {
setPlaceholderValue(`${addedItems.length} vald`);
} else if (addedItems.length > 1) {
setPlaceholderValue(`${addedItems.length} valda`);
} else {
setPlaceholderValue(placeholder);
}
}, [addedItems, placeholderValue, placeholder]);
useEffect(() => {
handleFilterData(searchTerm);
}, [searchTerm, addedItems, handleFilterData]);
useEffect(() => {
let isMounted = true;
if (isMounted) {
if (addedItems) {
updateAddedState();
}
}
return () => {
isMounted = false;
};
}, [updateAddedState, addedItems]);
return (
<div id="dropdownMulti">
<section className="inputSection">
<input
type="text"
placeholder={placeholderValue}
className="inputSection__input"
onChange={handleFilter}
value={searchTerm}
onFocus={onFocus}
onBlur={onBlur}
/>
<div className="inputSection__icon-container">
{inputActive ? (
<AiOutlineUpCircle
onClick={() => setInputActive(false)}
className="inputSection__icon-container--up"
/>
) : (
<AiOutlineDownCircle className="inputSection__icon-container--down" />
)}
</div>
</section>
<section className="addedItems-section">
{inputActive &&
addedItems.map((addedItem) => {
return (
<div className="addedItem" key={addedItem.id}>
<p className="addedItem__item">{addedItem?.name}</p>
<button
data-testid="remove-btn"
className="addedItem__button"
onMouseDown={(e: React.MouseEvent) =>
removeItem(addedItem, e)
}
>
<AiOutlineCloseCircle />
</button>
</div>
);
})}
</section>
{inputActive && (
<ul className="dataResult">
{filteredData.slice(0, 10).map((value) => {
return (
<li
className="dataResult__item"
key={value.id}
tabIndex={0}
onMouseDown={() => addItem(value)}
>
{value.name}
</li>
);
})}
</ul>
)}
</div>
);
};

关于如何减少运行次数有什么建议吗?

尝试删除React严格模式,它使组件只在开发中渲染两次,而不是在生产中。如果是这样的话,就穿回去。

尝试从useCallback函数的依赖项数组中删除updateState函数

const updateAddedState = useCallback(() => {
console.log("running");

updateState(addedItems);
}, [addedItems]);

如果它仍然不工作,定义updateState函数,该函数与props一起带有useCallback钩子,该钩子定义了该函数。

相关内容

  • 没有找到相关文章

最新更新