useState使用和原理
Hooks 是 React 16 中的特性,解决函数组件想使用类组件的一些特性。
关于更多 Hooks 介绍,请参考 React 官网[1]
useState
之前是在类组件中使用状态通过 state 定义,大概代码是这样的。
import React from 'react'; class Counter extends React.Component { state = { number: 0 } handleClick = () => { this.setState({ number: this.state.number + 1 }) } render() { return ( <> <p>{this.state.number}</p> <button onClick={ this.handleClick }> 改数字 </button> </> ); } } function render() { ReactDOM.render(<Counter />, document.getElementById('root')); } render()
但是函数组件没有实例,也没有状态。函数组件使用状态需要使用 useState 钩子。
关于 useState 的用法是,需要传入一个参数作为状态的初始值,当函数执行后会返回两个值,一个是当前状态的属性,一个是修改状态的方法。
我们通过一个计数器的例子,当点击按钮表示状态加1。
import React, {useState} from 'react'; function Counter() { const [ number, setNumber ] = useState(0) return ( <> <p>{number}</p> <button onClick={ () => setNumber(number + 1) } > 改数字 </button> </> ) } function render() { ReactDOM.render(<Counter />, document.getElementById('root')); } render()
现在我们已经掌握了它的用法,那么我们开始分析它的原理。
原理
我们需要写一个 useState 方法,会返回当前状态的属性和设置状态的方法,每当状态改变之后,方法中会调用刷新视图的 render 方法。
let memoizedState; function useState (initialState) { memoizedState = memoizedState || initialState function setState (newState) { memoizedState = newState render() } return [memoizedState, setState] }
再次尝试之前的代码,依然可以正常使用,但是当多个 useState 存在的时候就有问题了,只能变一个状态了。
function Counter() { const [ number, setNumber ] = useState(0) const [ title, setTitle ] = useState('随机标题') return ( <> <h1>{title}</h1> <p>{number}</p> <button onClick={ () => setNumber(number + 1) } > 改数字 </button> <button onClick={ () => setTitle(`随机标题${Math.random()}`) } > 改标题 </button> </> ) }
现在我们需要优化我们的 Hooks ,解决多个 useState 同时使用的问题,当多个状态存在的时候,我们需要使用数组保存状态。
let memoizedStates = [] let index = 0 function useState (initialState) { memoizedStates[index] = memoizedStates[index] || initialState let currentIndex = index function setState (newState) { memoizedStates[currentIndex] = newState render() } return [memoizedStates[index++], setState] } function Counter() { const [ number, setNumber ] = useState(0) const [ title, setTitle ] = useState('随机标题') return ( <> <h1>{title}</h1> <p>{number}</p> <button onClick={ () => setNumber(number + 1) } > 改数字 </button> <button onClick={ () => setTitle(`随机标题${Math.random()}`) } > 改标题 </button> </> ) } function render() { index = 0 ReactDOM.render(<Counter />, document.getElementById('root')); } render()
现在已经完成了 useState 的基本原理,当你了解原理之后,使用 Hooks 就变得更加容易了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构