1、根本应用:
const [state,setState]=useState(initValue);
- useState函数接管一个初始化参数initialState,其返回值用数组解构出两个参数:state和setState
- 在初始化渲染期间,返回的状态 (state) 与传入的第一个参数 (initialState) 值雷同
- setState 函数用于更新 state。它接管一个新的 state 值并将组件的一次从新渲染退出队列
- 在后续的从新渲染中,useState 返回的第一个值将始终是更新后最新的 state
2、两种更新形式
useState的更新state分为两种,间接更新和函数式更新。
- 间接更新
这个很好了解,间接传入新的state值即可,这种状况实用于与返回的新值与旧值不存在依赖关系。
setState(newState)
- 函数式更新
这个新的state的值须要用一个函数来返回,preState总能拿到上一次更新胜利之后的最新状态。
setState((preState)=>{return nextState})
区别:
如果失常应用,这两种形式没啥区别,然而如果是异步更新的话,他们之间的差异就会体现进去了
function Counter() { const [count, setCount] = useState(0); function handleClick() { setTimeout(() => { setCount(count + 1) }, 3000); } function handleClickFn() { setTimeout(() => { setCount((prevCount) => { return prevCount + 1 }) }, 3000); } return ( <> Count: {count} <button onClick={handleClick}>+</button> <button onClick={handleClickFn}>+</button> </> );}
当设置为异步更新,点击按钮提早到3s之后去调用setCount函数,当疾速点击按钮时,也就是说在3s屡次去触发更新,然而只有一次失效,因为 count 的值是没有变动的。
而当应用函数式更新 state 的时候,这种问题就没有了,因为它能够获取之前的 state 值,也就是代码中的 prevCount 每次都是最新的值。
这是因为应用函数更新的时候,setCount函数将会被放在一个工作队列中,每一个setCount函数都能够拿到上一次更新胜利后状态值。
留神:
- 如果你的更新函数的返回值齐全与以后的state雷同,则随后的渲染就会跳过
- hooks中的useState与class中setState不同,useState 不会主动合并更新对象,这里能够应用函数式的setState联合开展运算符达到合并的目标
3、惰性初始化state
initialState 参数只会在组件的初始渲染中起作用,后续渲染时会被疏忽。如果初始 state 须要通过简单计算取得,则能够传入一个函数,在函数中计算并返回初始的 state,此函数只在初始渲染时被调用:
const [state, setState] = useState(() => { const initialState = someExpensiveComputation(props); return initialState;});