Fork me on GitHub

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;
posted @   spikezz  阅读(346)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
1
点击右上角即可分享
微信分享提示