持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
useReducer
我们前面已经学习过useState了,而useState还有一个马甲,那就是useReducer,我们来尝试使用useReducer改写之前的useState
const reducer = (state, action) => {
switch (action.type) {
case 'add':
return state + 1
default:
break
}
}
const TestLogin = (props) => {
// const [count, setCount] = useState(() => fibonacci(40))
const [count, countDispatcher] = useReducer(reducer, 0)
const handleClick = () => {
// 第一种
// setCount(count + 1)
// 第二种
// setCount(prevCount => prevCount + 1)
countDispatcher({type: 'add'})
}
return <>
{count}
<button onClick={handleClick}>测试</button>
</>
}
export default React.memo(TestLogin)
这么写代码好像变多了?这是因为 useReducer 比起 useState 增加了额外的抽象,引入了dispatch 、action 、reducer 概念。这与著名应用状态管理框架 Redux 基本是对应的。说到马甲,其实 useState 底层就是基于 useReducer 实现的,useState 才是马甲。useReducer 适用于抽象封装复杂逻辑.
useRef
props 和 state 都是不可变的(Immutable)。那么,如果需要在 React 组件中使用可变值该怎么办?答案是,我们可以使用 useRef 这个 Hook。
调用 useRef 会返回一个可变 ref 对象,而且会保证组件每次重新渲染过程中,同一个 useRef Hook 返回的可变 ref 对象都是同一个对象。可变 ref 对象有一个可供读写的 current 属性,组件重新渲染本身不会影响 current 属性的值;反过来,变更 current 属性值也不会触发组件的重新渲染。
然后是 HTML 元素的 ref 属性。这个属性是 React 特有的,不会传递给真实 DOM。当 ref 属性的值是一个可变 ref 对象时,组件在挂载阶段,会在 HTML 元素对应的真实 DOM 元素创建后,将它赋值给可变 ref 对象的 current 属性,即 inputElem.current;在组件卸载,真实 DOM 销毁之前,也会把 current 属性设置为 null。
const TestLogin = (props) => {
// const [count, setCount] = useState(() => fibonacci(40))
const [count, countDispatcher] = useReducer(reducer, 0);
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus()
}, [])
const handleClick = () => {
// 第一种
// setCount(count + 1)
// 第二种
// setCount(prevCount => prevCount + 1)
countDispatcher({type: 'add'})
}
return <>
{count}
<input type="text" value={count} ref={inputRef} />
<button onClick={handleClick}>测试</button>
</>
}
总结
截止今天 我们学习了三个与状态相关的hook,分别是useState, useReducer, useRef,基本可以涵盖我们的日常状态管理的需求了。后续我们会继续学习useEffect,useCallback等其他hook,明天见。