【发布时间】:2021-02-05 13:54:12
【问题描述】:
我想在某些数据更改时执行副作用,例如
const useSearchResults = () => {
const location = useLocation();
const [data, setData] = useState();
useEffect(() => {
Api.search(location.query.q).then(data => setData(data));
}, [location.query.q]);
// Compute some derived data from `data`.
const searchResults =
data &&
data.map(item => ({
id: item.id,
name: `${item.firstName} ${item.lastName}`
}));
return searchResults;
};
const Component = () => {
const searchResults = useSearchResults();
useEffect(() => {
alert('Search results have changed'); // Side-effect
}, [searchResults]);
return <pre>{JSON.stringify(searchResults)}</pre>;
};
如果某些原因导致 Component 重新渲染,即使 searchResults 没有更改,alert 也会触发,因为我们映射了 useSearchResults 中的底层稳定数据,在每次渲染时创建一个新实例。
我最初的方法是使用useMemo:
// Stabilise `searchResults`'s identity with useMemo.
const searchResults = useMemo(
() =>
data &&
data.map(item => ({
id: item.id,
name: `${item.firstName} ${item.lastName}`
})),
[data]
);
但是useMemo has no semantic guarantee 所以它(理论上)只对性能优化有好处。
React 是否为这个(常见的?)问题提供了直接的解决方案?
【问题讨论】:
-
过去我使用 reselect 从解决了这个问题的 redux 存储中获取数据,但是考虑到它一次只存储 1 个值,所以如果你有多个实例,这有点复杂您需要创建一个选择器的多个实例,这很繁琐。
-
做一些研究,我在这里找到了一些详细的讨论github.com/facebook/react/issues/15278,这使我找到了github.com/alexreardon/use-memo-one,这似乎可以解决问题,但是鉴于该软件包不是很受欢迎,我很困惑为什么这是一个更广泛记录/解决的问题????
标签: javascript reactjs react-hooks