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