目錄
- useState
- 案例1(直接修改狀態)
- 案例2(函數式更新)
- 案例3(受控表單綁定)
- 注意事項1:set函數不會改變正在運行的代碼的狀態
- 注意事項2:set函數自動批量處理
- 注意事項3:在下次渲染之前多次更新同一狀態
- 最后
React官方文檔
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); // 0setCount(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