React hooks 之 useState
一、useState的介绍
useState是react自带的一个hook函数,它的作用是用来声明状态变量
声明的方式
const [ count , setCount ] = useState(0)
注意:这是数组的解构赋值的方式,如果不用解构赋值,则:
let _useState = useState(0) let count = _useState[0]
let setCount = _useState[1]
例子:
import React, { useState } from 'react'
//点击按钮,对点击次数计数
//函数组建的方法
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
import React, { Component } from 'react'
//点击按钮,对点击次数计数
//类组件的方法
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})
}
}
二、多状态声明及注意事项
多状态声明:
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出现的顺序来确定的。
我们可以加个判断语句试试
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>
)
}
可以看到的是,程序直接报错
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事件中改变状态),那么此时就会将多次改变状态合并在一起最终变化,提高效率。
此时不能信任新的值,而是应该使用回调函数的形式(即以下代码的注释部分)
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;

浙公网安备 33010602011771号