重学React(二)-- 其他状态Hooks

持续创作,加速成长!这是我参与「掘金日新计划 · 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,明天见。

文章目录