React hooks 之 useState
一、useState的介绍
useState是react自带的一个hook函数,它的作用是用来声明状态变量
声明的方式
1 | const [ count , setCount ] = useState(0) |
注意:这是数组的解构赋值的方式,如果不用解构赋值,则:
1 2 | let _useState = useState(0) let count = _useState[0]<br> let setCount = _useState[1] |
例子:
1 2 3 4 5 6 7 8 9 10 11 | import React, { useState } from 'react' //点击按钮,对点击次数计数<br>//函数组建的方法 export default function App() { const [ count , setCount ] = useState(0) return ( <div> You clicked {count} times. <button onClick={()=>{setCount(count+1)}}>click me</button> </div> ) } |
同样的功能相较于函数组件,类组件则更加繁琐:需要绑定this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import React, { Component } from 'react' <br> //点击按钮,对点击次数计数 //类组件的方法 export default class App extends Component { constructor(props){ super (props) this .state = { count : 0 } } render() { return ( <div> You clicked { this .state.count} times. <button onClick={ this .addCoount.bind( this )}>click me</button> </div> ) } addCoount(){ this .setState({count: this .state.count+1}) } } |
二、多状态声明及注意事项
多状态声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import React, {useState} from 'react' // useState多状态声明 export default function App() { const [ age, setAge ] = useState(24) const [ sex, setSex ] = useState( '男' ) const [ job, setjob ] = useState( '前端工程师' ) return ( <div> <p>spikezz今年{age}岁</p> <p>性别:{sex}</p> <p>工作是{job}</p> </div> ) } |
这里在使用useState的时候只赋了初始值,并没有绑定任何的key,那么react是怎么保证这三个useState找到它自己对应的state呢
其实,react是根据useState出现的顺序来确定的。
我们可以加个判断语句试试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import React, {useState} from 'react' // useState多状态声明时,加入条件语句 let flag = true export default function App() { const [ age, setAge ] = useState(24) if (flag){ const [ sex, setSex ] = useState( '男' ) flag = false } const [ job, setjob ] = useState( '前端工程师' ) return ( <div> <p>spikezz今年{age}岁</p> <p>性别:{sex}</p> <p>工作是{job}</p> </div> ) } |
可以看到的是,程序直接报错
1 | React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render |
即:React Hook “useState”被有条件地调用。在每个组件渲染中,必须以完全相同的顺序调用React Hooks
三、使用细节
1、useState尽量写在函数组件的开始部分,以方便阅读
2、useState不要写在循环体或者判断语句里
3、useState返回的第二个值(setXxx)引用是不变的,目的是节约内存空间
4、使用第二个返回值函数(setXxx)改变数据,如果新的数据和旧的数据是完全一样的(Object.is比较),那么组件不会重新渲染
5、使用第二个返回值函数(setXxx)改变函数,如果新旧数据不一样,新数据会直接替换旧数据,而不会合并
6、如果要实现强制刷新组件:
类组件:this.forceUpdate()
函数组件:给setXxx函数传入一个空对象
7、如果某些组件之间没有必然的联系,那么尽量写成多个状态的形式,不要合并成一个对象
8、和类组件的改变状态一样,函数组件改变状态时也是异步的(dom事件中改变状态),那么此时就会将多次改变状态合并在一起最终变化,提高效率。
此时不能信任新的值,而是应该使用回调函数的形式(即以下代码的注释部分)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import React, { useState, useEffect } from 'react' ; // 点击按钮,对点击次数计数 // 函数组件 function App() { const [count, setCount] = useState(0); useEffect(() => { console.log(`useEffect=>You clicked ${count} times`) }) return ( <div> <p>You clicked {count} times</p> <button onClick={() => { // 可以观察到的是,两次setCount只会有执行一次的效果 // 因为在Dom中状态的改变是异步的,就会将多个状态改变合并在一起 setCount(count + 1) setCount(count + 1) // 通过回调函数修改的话可以执行成功 // setCount(count => count+1) // setCount(count => count+1) }}>click me</button> </div> ) } export default App; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理