我已经使用两个状态变量来过滤颜色search, resultantColors
。
现有的 useEffect 会监视输入中的搜索,然后设置过滤后的数组。但这些效果会在每次输入更改时运行,我如何才能将 useEffect 重构为 useMemo,以便能够减少重新渲染?
另外,由于我们想要重构现有的 useEffect(组件 DidUpdate 生命周期),useMemo 是否支持 componentDidMount(空数组依赖项)、componentWillUnmount 的所有生命周期方法? ——对这个可以回答是或否。
我尝试减少重新渲染,但对于此示例,useEffect 会在每次更改时运行,每次都会触发。此外,useMemo 是否处理 useEffect 的所有等效生命周期?
import { useEffect, useState } from 'react';
function App() {
const mockColors = ['white', 'blue', 'yellow', 'green', 'orange', 'purple'];
const [search, setSearch] = useState('');
const [resultantColors, setResultantColors] = useState(mockColors);
const handleInputChange = (e) => {
setSearch(e.target.value);
};
useEffect(() => {
if (search == '') {
setResultantColors(mockColors);
} else {
const resultColors = resultantColors.filter((color) =>
color.toLowerCase().includes(search.toLowerCase())
);
setResultantColors(resultColors);
}
}, [search]);
return (
<div style={{ border: '1px solid blue', padding: 20, margin: 20 }}>
Filter Example with UseEffect <br />
<label htmlFor="colors">Filter Color:</label>
<input
type="search"
name="search"
value={search}
id="colors"
onChange={(e) => {
handleInputChange(e);
}}
placeholder="filter colors"
/>
{resultantColors.length > 0 ? (
resultantColors.map((value, index) => (
<>
<li key={`${value} + ${index}`}>{value}</li>
</>
))
) : (
<p>No items - search existing value </p>
)}
</div>
);
}
export default App;
删除
resultantColors
状态,并在每次发生变化时计算它search
:由于我们想要重构现有的 useEffect(组件 DidUpdate 生命周期),useMemo 是否支持 componentDidMount(空数组依赖项)、componentWillUnmount 的所有生命周期方法?
useMemo
如果依赖项参数相同,则返回缓存值;如果依赖项发生变化,则重新计算值。在挂载时,它会计算值并第一次缓存它,而在卸载时它不执行任何操作。如果您想在卸载时执行某些操作或处理任何副作用,您仍然必须使用。您可以使用和块useEffect
的组合(可以使用多个)来处理不同的情况。useMemo
useEffect
首先回答你的第二个问题:不,useMemo 不像 useEffect 那样支持所有生命周期方法。useMemo 主要用于记忆计算值,而 useEffect 用于副作用。useMemo 没有与 componentDidMount 或 componentWillUnmount 直接等同的功能。
我可能遗漏了一些东西,但这难道不能满足您的需要吗?
我将 mockColors 的常量移到了 App 声明之外。您还应该考虑对搜索值的变化进行反跳处理,这样它就不会导致记忆项圈频繁更改。SO 上有很多示例,例如这个:https: //stackoverflow.com/a/24004942/23356563