State Hook
State Hook 是一个在函数组件中使用的函数(usestate),用于在函数组件中使用状态
- useState()返回的是一个数组,包含两个元素
- 第一项为当前状态的值
- 第二项:改变状态的函数
一个函数组件中可以有多个状态,这个做法非常有利于横向切分关注点
State Hook原理
- 当运行一个函数组件时(调用该函数时),会在运行函数组件的组件上生成一个表格,储存状态的下标和值,调用函数就会查找下标,没有就新建,有就直接使用
注意细节
- useState最好写到函数的起始位置,便于阅读
- useState严禁出现在判断、循环中
- useState返回的第二个元素(改变状态的函数),引用不变(节约内存空间)
- 如果使用函数改变数据,若数据和之前的数据完全相等(使用Object.is比较),不会导致重新渲染,从而提高效率
- 使用函数改变数据,传入的值不会和原来的数据进行合并,而是直接替换
- 如果需要强制属性组件:
- 类组件:调用forceUpdate函数
- 函数组件:使用一个空对象的sueState
- 如果某些状态之间没有必要的联系,应该分化为不同的状态,而不要合并成一个对象(程序设计减少耦合度)
- 和类组件状态一样,函数组件中改变状态可能是异步的(dom事件中),多个状态变化会合并以提高效率,此时,不能信任之前的状态,而应该使用回调函数的方式来改变状态获取之前的状态,如果状态变化要使用到之前的状态,尽量传递函数,例如下面对比
export default function App() {
const [Num, setNum] = useState(0)
const [Price, setPrice] = useState(0)
return (
<div>
<p>数字:{Num}</p>
<button onClick={()=>{
setNum(Num+1)
setTimeout(() => {
setNum(Num+1) //如果异步多次调用,则最终会合并,建议使用回调函数设置状态,可以得到准确的上一个状态,这里直接使用则只会加1
}, 1000); //错误用法,直接使用仅仅适用事件里只设置一次状态
}}>+2</button>
<p>价格:{Price}</p>
<button onClick={()=>{
setPrice(prePrice=>prePrice+1)
setTimeout(() => {
setPrice(prePrice=>prePrice+1) //如果异步多次调用,则最终会合并,建议使用回调函数设置状态,可以得到准确的上一个状态
}, 1000); //正确用法,适用事件里只设置多次状态,可获取上一个暂存的状态
}}>+2</button>
</div>
)
}