视图更新必须得用usestate,不然视图并不会更新
结构:接受一个初始值,返回一个数组,这个数组里面第一个是默认值,第二个是set函数,更改值
数据类型的处理
简单数据类型:
如string bool int可以直接改
复杂数组类型::
复杂类型数组:不能操作原数组,需要创建一个新数组,不可以直接修改原数组,例如:不可以调用
arr.push()arr.pop()等方法。新增:数组解构[..arr]
删除:filter 和slice 它两返回新数组,所以用这个二个
修改: map arr.map(item=>item==‘小满’?‘瓜娃子’:item)
插入: slice const start =0 cost end=2
setArr([…arr.slice(start ,end),’瓜娃子’,…arr.slice(end)])
对象
setObject({ ...obj, name: '大满' })
第二种写法setObject(Object.assign({}, obj, { age: 26 }))
更新机制
异步更新
执行顺序
先执行1.同步任务(console.log)
接着2.异步任务( setIndex(index + 1)
此处先执行console.log,在执行 setIndex(index + 1)。
是因为 setIndex(index + 1)是异步任务。同步代码先走,所以先执行console.log(index,'index')。
function App() {
let [index, setIndex] = useState(0)
const heandleClick = () => {
setIndex(index + 1)//异步任务
console.log(index,'index') //0 同步代码先走,所以此处代码先执行
}
return (
<>
<h1>Index:{index}</h1>
<button onClick={heandleClick}>更改值</button>
</>
)
}
export default App
为什么要这是异步的呢? 这样做的目的是为了性能优化。
例如:为什么结果是1并不是3,因为setIndex(index + 1)的值是一样的,后续操作被屏蔽掉了,阻止了更新。
function App() {
let [index, setIndex] = useState(0)
const heandleClick = () => {
setIndex(index + 1) //1
setIndex(index + 1) //1
setIndex(index + 1) //1
console.log(index,'index')
}
return (
<>
<h1>Index:{index}</h1>
<button onClick={heandleClick}>更改值</button>
</>
)
}
export default App
执行setState发生了什么?
把这个setState推到队列中,在队列中会有一个判断,如果执行了重复性的操作,如一直setIndex(index + 1) //1,这个setIndex(index + 1) 会被阻断,它最后只执行了一次,自带防抖效果。然后还会等到所有的set函数执行完之后,才会去通知render渲染组件,更新视图
为了解决这个问题,你可以向setIndex 传递一个更新函数,而不是一个状态。
import { useState } from "react"
function App() {
let [index, setIndex] = useState(0)
const heandleClick = () => {
setIndex(index => index + 1) //1
setIndex(index => index + 1) //2
setIndex(index => index + 1) //3
}
return (
<>
<h1>Index:{index}</h1>
<button onClick={heandleClick}>更改值</button>
</>
)
}
export default App