React Hooks:UseEffect、UseCallback、UseMemo
使用效果
useEffect 示例
使用备忘录
使用回调
进一步阅读
React 自带了一大堆 Hooks,如果一次性学习它们,可能会有点难以掌握。这篇文章应该能帮助你理解其中三个 Hooks 的区别和用例。
使用效果
纯组件仅与其自身及其子组件交互。任何时候你需要与组件外部的世界交互,你都会处理副作用。
React 为我们提供了一个方便的钩子来处理这些问题。该React.useEffect
钩子让我们指定一个处理外力的函数,提供第二个函数来清理它,并删除依赖项列表,以便我们可以在其中一个依赖项发生变化时重新运行效果。
useEffect 示例
更新页面标题
此效果将在第一次渲染组件时运行,并且只有在标题发生变化时才会再次运行。
const [title, setTitle] = React.useState("Hooks 101");
React.useEffect(() => {
document.title = title;
}, [title]);
从 API 获取数据并放入本地状态。
由于我们的状态变化不会影响返回的产品列表,我们可以传递一个空数组[]
作为我们的依赖项,以便效果仅在首次安装组件时运行。
const [products, setProducts] = React.useState([]);
React.useEffect(() => {
getProducts()
.then(products => {
setProducts(products);
})
}, []);
根据查询,从 API 获取数据并放入本地状态。
如果我们有一个查询或过滤器来修改我们想要的 API 数据集,那么我们可以将其作为依赖项传递,以确保 React 每次使用新查询渲染组件时都运行此效果。
const [products, setProducts] = React.useState([]);
const [query, setQuery] = React.useState("");
React.useEffect(() => {
getProducts({name: query})
.then(products => {
setProducts(products);
})
}, [query]);
调度 Redux 动作。
如果您的 GET 操作已经减少到您的 Redux 状态,那么您不需要在本地维护任何内容。
通过作为依赖项传递products.length
,您只需运行此
const dispatch = Redux.useDispatch();
const products = Redux.useSelector(state => state.products);
React.useEffect(() => {
dispatch(GetProducts())
}, []);
使用备忘录
与 useEffect 不同,React.useMemo
每次更改其依赖项之一时不会触发。
记忆函数会首先检查依赖项自上次渲染以来是否发生了变化。如果是,则执行该函数并返回结果。如果否,则直接返回上次执行的缓存结果。
这对于昂贵的操作非常有用,例如转换 API 数据或进行您不想不必要地重新进行的重大计算
useMemo 示例
const posts = Redux.useSelector(state => state.posts);
const tags = React.useMemo(() => {
return getTagsFromPosts(posts)
}, [posts]);
使用回调
这是记忆函数的一个特例。由于 JavaScript 通过引用比较相等性,因此组件首次渲染时创建的函数将与后续渲染时创建的函数不同。
如果你尝试将函数作为 props 或 state 传递,这意味着每次都会将其视为 props 更改。通过将其包装在 useCallback 中,React 会知道它是同一个函数。你仍然可以添加依赖项数组,以便在依赖项发生变化时触发重新计算。
这里有一个强有力的用例,可以避免子组件重新渲染
useCallback 示例
每次此组件渲染时,它还会触发整个 Button 组件的重新渲染,因为removeFromCart
每次函数都是唯一的。
const dispatch = useDispatch();
const removeFromCart = () => dispatch(removeItem(product.id));
return (
<Button onClick={removeFromCart}>Delete</Button>
);
用这个替换我们的回调函数可以完全避免这个问题。现在,按钮只会在产品 ID 发生变化时重新渲染,这样它就能从购物车中移除新产品了。
const removeFromCart = React.useCallback(() => {
dispatch(removeItem(product.id))
}, [product.id]);
进一步阅读
https://overreacted.io/a-complete-guide-to-useeffect/
https://medium.com/@vcarl/everything-you-need-to-know-about-react-hooks-8f680dfd4349
https://kentcdodds.com/blog/usememo-and-usecallback
https://www.robinwieruch.de/react-hooks-fetch-data/
文章来源:https://dev.to/devcord/react-hooks-useeffect-usecallback-usememo-3o42