个人对React Hooks的理解(二)
这是个人对React Hooks的理解 以及部分原理解析。内容可能不完全正确,仅供参考。
React Hooks
useEffect
useEffect的第一个参数是回调函数,第二个参数是依赖数组。 它接收一个函数,并可以返回一个清理函数。
useEffect(() => {
console.log('effect');
return () => {
console.log('cleanup');
};
}, []);
1. 它出现解决了什么问题
- useEffect的出现解决了类组件中难以处理副作用的问题。
- 在类组件中,我们通常需要使用componentDidMount、componentDidUpdate、componentWillUnmount来处理副作用。
- 但是这些方法在函数组件中无法使用,所以useEffect的出现让我们可以更方便地处理副作用。
- 而且写Class类的生命周期函数,会让代码变得臃肿,难以维护。
2. useEffect的执行时机
- useEffect的执行时机是组件挂载后和每次更新后。
- 当组件挂载后,会执行useEffect的回调函数。
- 当依赖数组中的值发生变化时,会执行useEffect的回调函数。
什么是副作用?
- 副作用是指在函数组件中,除了渲染之外的其他操作。 比如我们需要调用api得到数据,这个就叫做副作用。 副作用会影响组件的渲染,所以需要使用useEffect来处理。
useCallback
useCallback是React提供的一个用于记忆化函数的Hook。 她跟React.memo很像,都是用于记忆化的。
1. 它出现解决了什么问题?
- 避免组件的频繁渲染
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]); // 依赖于 count,只有 count 变化时才会重新创建 handleClick
return <Child onClick={handleClick} />;
}
function Child({ onClick }) {
useEffect(() => {
console.log("Child rendered");
});
return <button onClick={onClick}>Click me</button>;
}
- 当依赖数组中的值a、b发生变化时,handleClick函数才会重新创建。
- 当依赖数组中的值a、b没有发生变化时,会返回原来的handleClick。 当子组件引用了useCallback包裹的handleClick时,当父组件的count发生变化时,子组件不会重新渲染。这样就解决了性能问题。
useContext
useContext是React提供的一个用于上下文传递的Hook,这个Hook返回一个组件。 它可以将上下文传递给所有子代组件。
1. 有什么用?
- useContext 用于访问通过 Context.Provider 提供的上下文值。
- 它让你能够轻松地从上下文中获取数据,而不需要手动传递每个组件的 props。
- 通过 useContext,我们可以避免 props 层层传递的问题,简化跨组件的状态共享。
import React, { createContext, useState } from 'react';
// 创建上下文
const ThemeContext = createContext();
// 提供上下文值
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={theme}>
<Child />
</ThemeContext.Provider>
);
}
function Child() {
return <Grandchild />;
}
function Grandchild() {
return <Button />;
}
function Button() {
// 使用 useContext 获取上下文值
const theme = useContext(ThemeContext);
return <button>The current theme is {theme}</button>;
}