我使用了两个状态变量来过滤颜色
search, resultantColors
。
现有的 useEffect 监视输入中的搜索,然后设置过滤后的数组。但是这些效果会在每次输入更改时运行,我如何才能将 useEffect 重构为 useMemo,以便能够减少重新渲染?
另外,useMemo 是否支持 componentDidMount(空数组依赖)、componentWillUnmount 的所有生命周期方法,因为我们想重构现有的 useEffect(组件 DidUpdate 生命周期)? - 可以对此给出是或否。
我尝试减少重新渲染,但对于这个示例,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
变化时就计算:
const { useMemo, useState } = React;
const mockColors = ['white', 'blue', 'yellow', 'green', 'orange', 'purple'];
function App() {
const [search, setSearch] = useState('');
const handleInputChange = (e) => {
setSearch(e.target.value);
};
const resultantColors = useMemo(() =>
search == ''
? mockColors
: mockColors.filter(color =>
color.toLowerCase().includes(search.toLowerCase())
)
, [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={handleInputChange}
placeholder="filter colors"
/>
{resultantColors.length > 0 ? (
resultantColors.map((value, index) => (
<>
<li key={`${value} + ${index}`}>{value}</li>
</>
))
) : (
<p>No items - search existing value </p>
)}
</div>
);
}
ReactDOM
.createRoot(root)
.render(<App />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>