目录
useState
useState在组件的顶层调用来声明和操作状态变量。用法:
const [state, setState] = useState(initialState)
useState返回一个包含两个值的数组:
- state:当前状态。在第一次渲染时,它将匹配initialState传递的数据。
- setState:该set函数可将状态更新为不同的值并触发重新渲染。
set函数没有返回值
- initialState:状态的初始值,它可以是任何类型的值,如果是函数,则将函数返回值作为初始值
案例1(直接修改状态)
import {useState} from 'react'
function App(){
const [count,setCount] = useState(0);
return (
<>
<div>count:{count}</div>
<button onClick={()=>setCount(1)}>+</button>
</>
)
}
export default App
点击加号,页面中count
变成1,继续点击加号,count
值不变
案例2(函数式更新)
import {useState} from 'react'
function App(){
const [count,setCount] = useState(0)
const handlerClick = ()=>{
setCount(count+1)
}
return (
<>
<div>count:{count}</div>
<button onClick={handlerClick}>+</button>
</>
)
}
export default App
点击加号按钮,可以看到页面中数据改变,并且hooks中的State状态也随之改变
案例3(受控表单绑定)
import {useState} from 'react'
function App(){
// 1 先声明一个react 状态
const [value,setValue] = useState('')
//2 核心
// (1)通过value属性绑定react状态
// (2)绑定onChange事件,通过事件参数e拿到输入框的最新的值,反向修改react状态
return (
<>
<div>
<input
type='text'
value={value}
onChange={(e)=>setValue(e.target.value)}
></input>
</div>
</>
)
}
export default App
在输入框中输入“张三”,hooks中的State也随之改变
要点一:set函数是异步的,调用set函数后,不能立即获取最新的值
const [count,setCount] = useState(0)
const handlerClick = () => {
setCount(count+1)
console.log(count)//打印为0
}
const getCount = ()=>{
console.log(count,"count")
}
return (
<>
<div>count:{count}</div>
<button onClick={handlerClick}>+</button>
<button onClick={getCount}>获取set之后数据</button>
</>
)
先点击加号按钮
,会打印出“0”,随后点击获取set之后数据
按钮,打印出count为1,说明点击获取set之后数据
按钮时获取到了最新值。
注意事项1:set函数不会改变正在运行的代码的状态
set函数是异步的,调用set函数后,不能立即获取最新的值。
const [count,setCount] = useState(0)
function handleClick() {
console.log(count); // 0
setCount(count + 1); // 重新渲染
console.log(count); // 打印 0!
setTimeout(() => {
console.log(count); // 打印 0!
}, 5000);
}
return (
<div>count:{count}</div>
<button onClick={handleClick}>+</button>
)
这是因为状态的行为类似于快照。更新状态会请求使用新状态值进行另一次渲染,但不会影响count已在运行的事件处理程序中的 JavaScript 变量。
状态变量可能看起来像您可以读取和写入的常规 JavaScript 变量。但是,状态的行为更像是快照。设置它不会更改已有的状态变量,而是触发重新渲染。
如果需要更新后的状态,可以提前设置一个变量。
const nextCount = count + 1;
setCount(nextCount);
console.log(count); // 0
console.log(nextCount); // 1
注意事项2:set函数自动批量处理
React 18之前只会在只在合成事件与钩子函数中自动批量处理,在promise、setTimeout或js原生事件中,都不会进行批处理。
React 18之后,默认所有的更新都会自动批量处理,只渲染一次。**更新多个状态变量(甚至来自多个组件),不会触发太多重新渲染,在事件处理程序及其中的任何代码完成后,UI 才会更新。
设置状态只会在下一次渲染时更改它。在第一次渲染期间,info 为{ name: “张三”, age: 1 },这就是为什么在该渲染的onClick处理程序中,即使调用了setInfo,info的值依然为{ name: “张三”, age: 1 }
React等待事件处理程序中的所有代码运行完毕后再处理状态更新。这就是为什么重新渲染只发生在所有这些setInfo()调用之后。
const [info, setInfo] = useState({ name: "张三", age: 1 })
const handlerClick = () => {
setTimeout(() => {
setInfo({ ...info, name: "里斯" })
setInfo({ ...info, name: "1" })
setInfo({ ...info, name: "2" })
setInfo({ ...info, name: "3" })
setInfo({ ...info, name: "4" })
setInfo({ ...info, name: "5" })
setInfo({ ...info, name: "6" })
setInfo({ ...info, name: "7" })
setInfo({ ...info, name: "8" })
setInfo({ ...info, name: "9" })
setInfo({ ...info, name: "10" })
setInfo({ ...info, name: "11" })
setInfo({ ...info, age: "12" })
}, 0)
}
页面中显示为name-张三 age-12,只有age改变,name没有改变
注意事项3:在下次渲染之前多次更新同一状态
传递一个根据队列中的前一个状态计算下一个状态的函数setNumber(n => n + 1),比如。这是一种告诉 React “对状态值做一些事情”而不是仅仅替换它的方法。
这里,n => n + 1称为更新函数。当您将其传递给状态设置器时:
React 将此函数排队,以便在事件处理程序中的所有其他代码运行完毕后进行处理。
在下一次渲染期间,React 会遍历队列并提供最终更新的状态。
const [info, setInfo] = useState({ name: "张三", age: 1 })
setTimeout(() => {
setInfo((n)=>({ ...n, name: "里斯" }))
setInfo((n)=>({ ...n, age: 0 }))
}, 0)
页面中显示为name-里斯 age-0,name和age都改变
最后
ONLYOFFICE发布了一个插件比赛,面向所有人,为 ONLYOFFICE 开发适合中国用户的插件,可赢取税前5500 - 10000元的结项奖金与证书:https://mp.weixin.qq.com/s/DE1-n8fMli5PueCp4m-_KQ