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;});