
react 进阶hook 之 State Hook
多状态支持:一个组件可以拥有多个状态,实现了水平切分的优势 状态更新控制:只有状态发生变化时,组件才会重新渲染 数据浅合并原则:和类组件不同,状态更新是直接替代原数据,而不是浅合并 状态直接更新待任:可以通过
状态存储:使用一个隐藏的数组(memoizedState)来存储所有的状态值 状态获取:通过访问数组对应位置获取当前状态值 状态更新:通过调用数组第二项函数(setState)进行状态更新 更新判断:在进行状态更新时,先比较新旧数据是否一致,若相同则不会触发渲染
将 useState 放在组件顶部 避免在复杂条件下使用 记得 useState 会随着时间被重新渲染 加强对数据深比较的理解,减少不必要的更新
发布日期:2021-05-20 04:12:21
浏览次数:24
分类:精选文章
本文共 1956 字,大约阅读时间需要 6 分钟。
React 状态HOOK 实用指南
语法解析
状态HOOK 是 React 函数组件中使用状态的核心机制,通过 useState
函数可以轻松管理组件内部的状态数据。
基本用法
const [data, setData] = useState('初始值')
useState
函数接受一个初始值,并返回一个包含当前状态值和更新状态函数的数组。具体来说:
- 第一项:当前状态的值(
data
) - 第二项:用于更新状态的函数(
setData
)
核心特点
setData
手动更新状态,或基于前置状态条件执行更新状态更新场景
在 React 应用中,一些状态变化需要借助 DOM 事件或时间周期(如 useEffect):
setData(s => { const prev = s.data s.data = prev + 1 return s})
这种写法可以确保状态更新是基于最新状态的前置值,且不会出现遗漏或错位。
原理分析
useState
工作原理基于以下核心逻辑:
手动实现示例
// hooks 存放在这个数组let memoizedState = []let cursor = 0function useState(initialValue) { memoizedState[cursor] = memoizedState[cursor] || initialValue const currentCursor = cursor function setState(newState) { // 如果新值与当前值相同,不更新 if ( newState === memoizedState[currentCursor] ) return memoizedState[currentCursor] = newState cursor = currentCursor + 1 render() // 触发重新渲染 } return [memoizedState[cursor++], setState]}
注意事项
1. useState 最好放在组件顶部
目的:便于代码阅读,形成完整的逻辑块
2. 避免在判断或循环中使用 useState
if (条件) { const [data, setData] = useState(...)}
这样做会导致 hooks 在不同的渲染周期中重复调用,影响性能
3. useState 返回的函数是引用类型
const [data, setData] = useState(0)const arr = [setData]// setData 是同一个函数 reference
函数数组中的函数引用会被保存,避免多次调用创造新函数实例
4. 传入函数更新值时,确保不浪费计算
如果传入的值与当前状态相同,React 会自动停止更新,避免不必要的性能消耗
5. 如何实现强制重渲染
setData({})// 或者传入一个新的对象或数组
这种方法强制将状态更新作为新引用值,无论是否有内容修改都会触发渲染
案例应用
简单计数器
import React, { useState } from 'react'export default function TestStateHook() { const [data, setData] = useState(0) return ({data})}
如何正确使用 useState
通过遵循这些原则,可以让状态管理更加高效,代码质量提升,减少 bug 的发生概率。
作者声明
本文思想正文均经过多次优化,立场保持一贯,内容适配 React 状态HOOK 的实际应用场景。