react hooks

什么是Hook

hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他 React 特性。

Hook 官方文档:Hooks

class组件的不足

  1. 组件之间难以复用状态逻辑
  2. 复杂组件难以理解
  3. 使用 class 导致学习成本变高

hook 使用注意事项

  1. Hook 不能再 class 组件中使用
  2. 只能在函数最外层调用 Hook ,不能在循环、条件判断或者子函数中调用
  3. 只能在 React 的函数组件中调用, 不能在其他 Javascript 函数中调用

内置Hooks

一、useState

如果检测到当前的state没有发生任何改变,那么页面是不会发生重新渲染的

使用方法

// 定义
const [count, setCount] = useState(0)

1、基本数据类型

# 更新
# 1、直接调用 setCount 传入更新的数据
setCount(count + 1)
# 2、对于复杂的更新逻辑使用函数式更新
setState(() => count + 1)

2、引用数据类型,使用函数式更新结合扩展运算符

const [state, setState] = useState({})
// 给 setState 传递一个函数,可以接收上一次state的结果(prevState)
setState((prevState) => {
	return {
		...prevState,
		[key]: value
	}
})

3、惰性初始state
initialState 参数只会在组件的初始渲染中起作用,后续渲染时会被忽略

4、复杂初始state定义
初始 state 需要通过复杂计算获得,则可以传入一个函数,在函数中计算并返回初始的 state


二、useContext

接收一个 context 对象并返回该 context 的当前值,使用 useContext 可以实现跨级组件之间的数据通信

三、useEffect

React 在完成对Dom的更新后会执行,默认情况下,React会在每次渲染后调用副作用函数,包括第一次渲染的时候。
useEffect 有两个参数,第一个参数是副作用的处理函数,第二个参数是与该副作用关联的状态或属性依赖数组
# 如果只想在初始化运行一次,后续不想再运行,那么可以给第二个参数传递一个空数组 [],达到componentDidMount一样的效果
# 如果需要清除监听逻辑,则可以返回一个函数,在函数中处理清除逻辑
# 初始化 useEffect 会被执行两次,这不是BUG 而是React18 的新特性,是为了模拟立即卸载组件和重新挂载组件。仅在'development' 环境下且使用了严格模式  ('Strict Mode') 下才会触发,生产环境 'production' 模式下和原来一样,仅执行一次。
useEffect(() => {
	// 注册监听逻辑
	console.log(state, 'useEffect')
	// 清除监听逻辑
	return () => {
		// 清除监听逻辑
		// 这里的逻辑在下一次执行useEffect的时候优先执行
	}
}, [state])

四、useReducer

1、基础用法

# 接收三个参数,1、处理状态更新的reducer; 2、状态初始值; 3、状态初始化函数(可选),参数为第二个初始值,返回值为reducer的初始状态
const [state, dispatch] = useReducer(reducer, initialArg, init)

示例:

function reducer(state, action) {
	switch(action.type) {
		case 'increment':
			return { count: state.count + 1 }
		case 'decrement':
			return { count: state.count - 1 }
		case 'reset':
			return { ...state, ...action.payload }
		default:
			throw new Error()
	} 
}

function init(initialCount) {
	return { count: initialCount }
}

function Counter() {
	const [state, dispatch] = useReducer(reducer, 1, init)

	return (
		<div>
			<div>{ state.count }</div>
			<button onClick={() => dispatch({ type: 'increment' })}>+</button>
		</div>
	)
}

五、useCallback

在函数式组件中,定义在组件内的函数会随着状态值的更新而重新渲染,函数中定义的函数会被频繁定义,在父子组件的通信中这样是非常消耗性能的。
使用useCallback 结合 memo(React.memo) 可以有效的减少组件更新频率,提高效率

基本写法

# 第一个参数是处理函数,第二个参数是一个数组,用于指定被记忆函数更新所依赖的值,如果指定的值发生了变化,那么useCallback的处理函数就会被重新执行,否则useCallback始终返回上一次处理函数执行的结果(可以给useCallback第二个参数传递一个空数组,并将这个useCallback 当做props传递给其他组件,这样就不会导致子组件因为父组件的更新而被频繁更新)
const memoizedCallback = useCallback(
	() => {
		doSomething(a, b)
	},
	[a, b]
)

# React.memo用法, 只要传入的props 没有变动,那么组件就不会重新渲染
const Child = React.memo(function () {
	return (
		<div>child</div>	
	)
})

六、useMemo

1、把创建函数和依赖项数组作为参数传入 `useMemo`,它仅会在某个依赖项改变时才重新计算 memoized值。这种优化有助于避免在每次渲染时都进行高开销的计算。传入useMemo的函数会在渲染期间执行。
2、如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值。
3、传入的函数内部必须要有返回值
# 实现类似 vue 的computed
const [a, setA] = useState(0)
const [b, setB] = useState(0)

const c = useMemo(() => {
	return a + b
	// 也可以返回一段 dom
	// return <div>{a + b}</div>
}, [a, b])


持续更新中...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值