react 中常见的 Hooks
① useState:组件状态管理钩子
- useState 使函数组件能够使用state
-
基本使用
const { state, setState } = usetState(initState);
- state 是要设置的状态
- setState 是更新 state 的方法,只是一个方法名,可以随意修改。
- initState 是初始的 state,可以是随意的数据,也可以是回调函数,但是函数必须是有返回值。
import { useState } from 'react'; const App = ()=>{ const [ state, setState ] = useState(0); return( <div> <div>点击了{ count } 次</div> <Button onClick={()=>{setState(count + 1)}}>点击</Button> </div> ) }
② useEffect:副作用处理钩子
-
数据获取、订阅、定时执行任务、手动修改 ReactDOM 这些行为都可以称为副作用。而 useEffect 就是为了处理这些副作用。
-
useEffect 也是 componentDidMount、componentDidUpdate、componentWillUnmount这几个生命周期方法的统一。
-
useEffect 的基本使用
useEffect(callback, array)
- callback:回调函数,作用是处理副作用逻辑
- callback 可以返回一个函数,用作清理
useEffect(()=>{ // 副作用逻辑 return ()=>{ // 清理副作用需要清理的内容 // 类似于 componentWillUnmount,组件渲染和组件卸载前执行的代码 } }, [])
- array(可选参数):数组,用于控制 useEffect 的执行。
- 分三种情况
- 空数组,则只会执行一次(即初次渲染 render ),相当于 componentDidMount。
- 非空数组,useEffect 会在数组发生改变时执行。
- 不填 array 这个数组,useEffect每次渲染都会执行。
- 分三种情况
- callback:回调函数,作用是处理副作用逻辑
-
完整使用例子
import { useState, useEffect } from 'react'; const app = ()=>{ const [ count, setCount ] = useState(0); useEffect(()=>{ document.title = `您点击了${ count }次按钮`; return ()=>{ console.log('组件卸载或者更新了') } }, [count]) return ( <div> <div>你点击了{count}次</div> <Button onClick={()=>{setCount(count + 1)}}>点击</Button> </div> ) }
③ useContext:它是针对 context 上下文提出的一个 Hooks,它接受React.createContext()的返回值作为参数,即 context 对象,并返回最近的 context;
- 使用useContext不需要再使用 Provider 和 Consumer。
- 当最近的 context 更新的时候,那么使用该 context 的 hook 将会重新渲染。
- 基本使用如下:
const Context = React.createContext({ age: 18, name: 'jerry' });
// 组件1
const app = ()=>{
// 使用useContext
const ctx = useContext(Context);
return (
<div>姓名:{ ctx.name }</div>
<div>年龄:{ ctx.age }岁</div>
)
}
④ useReducer:是 useState
的增强体,可以用于处理复杂的状态管理
-
useReducer 可以完全替代 useState,只是简单的状态管理用useState比较易用
-
useReducer 的设计灵感源自于 redux 的 reducer
-
对比 usetState 和 useReducer
// useState 的使用方法
const { state, setState } = useState(initState);
// useReducer 的使用方法
const { state, dispatch } = useReducer(reducer, initState, initAction);
-
useReducer 的参数介绍
- reducer 是一个函数,根据 action 状态管理并更新 state
- initState 是初始化的 state
- initAction 是 useReducer 初次执行时被处理的 action
-
返回值 state, dispatch 介绍
- state 状态值
- dispatch 是更新state的方法,他接受action作为参数
-
useReducer 只需要调用 dispatch(action) 方法传入action 即可更新 state,使用如下
// dispatch 是用来更新 state的,当 dispatch 被调用的时候, reducer 也会被调用,同时根据 action 的传入内容去更新 state ,action 是传入的一个描述操作的对象 dispatch({type: 'add'})
-
reducer 是 redux 的产物,它是一个函数,主要用于处理
action
,然后返回最新的state,可以把reducer 理解成 action 和 state 的转换器,他会根据 action 的描述去更新 state, 使用例子(state, action) => { NewState }
-
具体使用例子
import React, { useReducer } from 'react';
const { initState } = { count: 0 }; // state 的初始值
const reducer = ( state, action )=>{
switch(action.type) {
case 'reset':
return initState;
case 'add':
return { count: state.count + 1 };
case 'reduce':
return { count: state.count - 1 };
default:
return state;
}
}
export default function Demo() {
const { state, dispath } = useReducer(reducer, initState);
return (
<div>
<p>当前数量是:{ state.count }</p>
<div>
<button onClick={()=>{ dispatch({ type: 'reset' }) }}>重置</button>
</div>
<div>
<button onClick={()=>{ dispatch({ type: 'add' }) }}>加一</button>
</div>
<div>
<button onClick={()=>{ dispatch({ type: 'reduce' }) }}>减一</button>
</div>
</div>
)
}
⑤ useMemo
-
useMemo 用于性能优化,通过记忆来避免每个渲染上执行高开销的计算,传入的 useMemo 的函数会在渲染期间执行,不能在 useMemo 里面写副作用处理逻辑,副作用的逻辑处理放在 useEffect 内进行处理。
- 适用于复杂的计算场景,例如复杂的列表渲染,对象拷贝等场景
- 使用方法如下:
const memoValue = useMemo(callBack, array);
- callback 是一个函数用于处理逻辑
- array 是控制 useMemo 重新执行的数组, array 改变时才会重新执行 useMemo
- useMemo 返回的是一个记忆值,是 callback 的返回值
const obj1 = { name: 'john', age: 18 } const obj2 = { name: 'alia', age: 20 } const memoValue = useMemo( () => Object.assign(obj1, obj2), [obj1, obj2] ); <div>姓名:{ memoValue.name }---年龄{ memoValue.age }</div>
-
不能在 useMemo 里面写副作用处理逻辑,副作用的逻辑处理放在 useEffect 内进行处理。
⑥ useCallback
-
useCallback 和 useMemo 一样,也是用于性能优化
const memoCallback = useCallback(callback, array);
- callback 是一个函数用于处理逻辑
- array 控制 useCallback 重新执行的数组,array 改变时才会重新执行 useCallback;
- 跟 useMemo 不一样的是,useCallback将返回回调函数的 memoized 版本,useMemo 的返回值是callback函数的返回值
useCallback(fn ,depts) 相当于 useMemo(()=> fn, deps)
;
const obj1 = { name: 'john', age: 18 } const obj2 = { name: 'alia', age: 20 } const memoCallback = useCallback(()=>Object.assign(obj1, obj2), [obj1, obj2]) <div>姓名:{ memoCallback().name }---{ memoCallback().age }</div>
⑦ useRef
const refContain = useRef(initValue);
-
useRef 返回的是一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initValue)。返回的 ref 对象在组件的政哥生命周期内保持不变。
-
本质上,useRef 就像是可以在 .current 属性中保存一个可变值的盒子
-
useRef 比 ref 属性更有用,它可以很方便的保存任何可变值,其类似于在 class 中使用实例字段的方式。这是因为它创建的是一个普通的 javascript 对象,而 useRef() 和 自建一个 { current: … }的区别是, useRef 会在每次渲染时都会返回一个 ref 对象。
const useRefComp = ()=>{
const inputRef = useRef()
const getValue = ()=>{
console.log(inputRef.current.value);
}
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={()=>{getValue()}}>获取input的值</button>
</div>
)
}