一、主要是讲一下类组件的状态和函数组件的状态
1.类组件中state只能有一个,
函数组件中state可以有多个
函数组件:可以使用多个状态,便于控制。
// 文章数量的初始值
const [articleData, setArticleData] = useState({
list: [],// 文章列表
count: 0,// 文章数量
})
const [info,setinfo] = useState("个人信息");
类组件
state ={
task:[],
number:0,
}
2.关于修改数据
- useState使用函数改变数据,传入的值不会和原来的数据进行合并,而是直接替换。
因为useState建议不同的状态分开,不要不同的状态混在一个用。所以每次都是替换。 - setState修改数据时,是合并。
3.如何强制刷新组件
- 类组件:使用forceUpdate函数
- 函数组件:使用一个空对象的useState
import React, { useState } from 'react'
// import React, { Component } from 'react'
// export default class App extends Component {
// render() {
// return (
// <div>
// <button onClick={()=>{
// //不会运行shouldComponentUpdate
// this.forceUpdate();//强制重新渲染
// }}>强制刷新</button>
// </div>
// )
// }
// }
export default function App() {
console.log("App Render");
const [, forceUpdate] = useState({});
return <div>
<p >
<button onClick={() => {
forceUpdate({});
}}>强制刷新</button>
</p>
</div>
}
二、useState原理
当运行一个函数组件时(即调用该函数),会执行函数
-
会调用useState,
-
.检查该节点的状态表格,是否存在对应的下标N;
-
不存在:
使用默认值创建一个状态
将该状态加入状态数组,下标为N
- 存在:
忽略默认值
直接得到状态值使用
所以尽管一个组件我们使用多次,每个函数组件都会用自己的状态数组,因为每个函数组件有自己独立的状态数组。这个状态数组记录了当前数组中每个state的值,所以useState严禁出现在代码块(判断、循环)中(容易导致下标混乱,得到状态不对应)
function App () {
const [count,setCount] = useState(1);
}
和类组件的状态一样,函数组件中改变状态可能是异步的(在DOM事件中),多个状态变化会合并以提高效率,此时,不能信任之前的状态,而应该使用回调函数的方式改变状态。如果状态变化要使用到之前的状态,尽量传递函数。
import React, { useState } from 'react'
export default function App() {
console.log("App render")
const [n, setN] = useState(0); //使用一个状态,该状态的默认值是0
return <div>
<button onClick={() => {
// setN(n - 1);
// setN(n - 1);
setN(prevN => prevN - 1); //传入的函数,在事件完成之后统一运行
setN(prevN => prevN - 1);
}}>-</button>
<span>{n}</span>
<button onClick={() => {
// setN(n + 1) //不会立即改变,等click事件运行完成之后一起改变
// setN(n + 1) //此时,当执行第二个setN时候,n的值仍然是0,n+1运行完还是1.
setN(prevN => prevN + 1); //传入的函数,在事件完成之后统一运行
setN(prevN => prevN + 1);
}}>+</button>
</div>
}