Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
1.使用类组件,相关逻辑的代码会被分割到不同生命周期函数中,比如订阅监听与解绑 ,需要在 componentDidMount 中注册监听,而却需要在componentWillUnMount中解绑。相关逻辑的代码被拆分到了不同的生命周期函数中,而毫无关联的代码又被放在同一个生命周期函数中(比如获取数据以及注册监听都会放到componentDidMount中),使用hook可以很好的优化这一问题,可以将不同逻辑的代码分开,相同逻辑的代码放到一起。
2.使用hook可以简化开发者的工作,使用hook,开发者可以不用理解javaScript中的this ,也不同给函数绑定this。
1.useState
使用示例:
const [state, setState] = useState(initialState);
useState接受初始值或者 函数(返回初始值) , 返回一个state以及更新state的函数
setState
函数用于更新 state。它接收一个新的 state 值并将组件的一次重新渲染加入队列
setState(newState);
函数式更新
如果新的state需要通过先前的state计算得出,则传递给setState一个函数,该函数接受原来的state作为参数,返回新的state,下面的例子展示了setState的两种用法
- function Counter({initialCount}) {
- const [count, setCount] = useState(initialCount);
- return (
- <>
- Count: {count}
- <button onClick={() => setCount(initialCount)}>Resetbutton>
- <button onClick={() => setCount(prevCount => prevCount - 1)}>-button>
- <button onClick={() => setCount(prevCount => prevCount + 1)}>+button>
- >
- );
- }
如果你的更新函数返回值与当前 state 完全相同,则随后的重渲染会被完全跳过。
使用示例:
- // 相当于componentDidMount
- useEffect(()=>{
- // ...
- },[])
-
- //相当于componentDidMount + componentDidUpdate
- useEffect(()=>{
- ...
- })
-
- // 相当于componentWillUnmount
- useEffect(()=>{
- ...
-
- return () => {
-
- }
- },[])
3.useCallback 和useMemo
useCallback和useMemo都是做优化工作的
它们的不同点:
useCallback | useMemo | |
返回值 | 一个缓存的函数 | 一个缓存值 |
参数 | 需要缓存的函数以及依赖 | 需要缓存的值以及依赖 |
使用场景 | 父子组件之间的优化 父组件传给子组件的props中有函数,当父组件更新时,函数会重新生成,函数的引用会改变,子组件的props会改变导致子组件重新渲染。使用useCallback可以将函数缓存下来,只有当依赖项改变时才会重新生成函数,依赖项没改变时会返回上一次的缓存函数,子组件的props就不会改变,子组件就不会重新渲染,以此提高了效率 | 单个组件的优化 有一些计算并不是组件每次渲染都需要执行的,可以将这些值缓存下来,如果组件重新渲染了,但是依赖项没有改变时,直接返回上一次的缓存值。减少了计算次数,以此提高了效率 |
4.useRef
useRef
返回一个可变的 ref 对象,其 .current
属性被初始化为传入的参数(initialValue
)。返回的 ref 对象在组件的整个生命周期内保持不变。
本质上,useRef
就像是可以在其 .current
属性中保存一个可变值的“盒子”。
使用示例:
- function TextInputWithFocusButton() {
- const inputEl = useRef(null);
- const onButtonClick = () => {
- // `current` 指向已挂载到 DOM 上的文本输入元素
- inputEl.current.focus();
- };
- return (
- <>
- <input ref={inputEl} type="text" />
- <button onClick={onButtonClick}>Focus the inputbutton>
- >
- );
- }