![](/img/trans.png)
[英]scrolling to bottom of page run function - function runs too many times.
[英]React useEffect causing function to run 7 times. I am using a useCallback but it still runs to many times
带有 console.log("running") 的 updateAddedState 函数在页面刷新/初始渲染中运行了 7 次。
我只希望 updateAddedState 函数在 addedItems 状态更新时运行一次。
我只在实际 addedItems 状态发生变化时运行 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 Strict Mode,它使组件仅在开发中渲染两次,而不是在生产中。 如果是这种情况,请重新安装。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.