hooks

作者: 狸子狸 | 来源:发表于2023-11-16 10:41 被阅读0次

    1.useState

    2.useEffect

    3.useContext 和createContext(使用上下文和创建上下文)

    useContext 用于接收祖先组件的 context 传递的信息。

    /**
     * @param { context } context:context 容器
     * @return { any } value:祖先组件传递的 context
     */
    const value = useContext(context)
    示例:
    
    // 1、创建 context 容器
    const NumberContext = createContext(null);
    
    // 2、祖先组件定义 Provider
    function GrandFather() {
      return (
        <NumberContext.Provider value={1}>
          <Father />
        </NumberContext.Provider>
      );
    }
    
    // 3、父组件中使用子组件
    function Father() {
      return (
        <Son></Son>
      )
    }
    
    // 4、子组件中通过 useContext 接收祖先组件传递的数据
    function Son() {
      const number = useContext(NumberContext);
    }
    

    useContext() 总是在调用它的组件 上面 寻找最近的 provider。它向上搜索,不考虑 调用 useContext() 的组件中的 provider。

    4.useReducer

    useReducer 能够在无状态组件中运行的类似 redux 的功能 api 。

    当对一个状态有多种处理逻辑时建议使用 useReducer。

    /**
     * @param { function } reducer:处理函数
     * @param { any } initValue:初始值
     * @param { function } compareInitValueFn:计算初始值的函数,如果存在则初始值为 compareInitValueFn(initValue)
     * @return { array } arr:状态信息
               state { any } 状态名
               dispatchState { function } 派发状态的函数
     */
    const [state, dispatchState] = useReducer(stateReducer, initValue, compareInitValueFn?)
    示例:
    
    const numberReducer = (state, action) => {
      switch(action.type) {
        case 'add':
          return state + 1;
        case 'reduce':
          return state - 1;
      }
    }
    const [number, dispatchNumber] = useReducer(numberReducer, 0);
    
    dispatchNumber({
      type: 'add'
    })
    

    5.useLayoutEffect

    useLayoutEffect 是 useEffect 的同步版本,并且是在浏览器绘制前执行,主要用于操作 DOM。
    useEffect 的函数会在组件渲染到屏幕之后执行
    useLayoutEffect则是在DOM结构更新后、渲染前执行,相当于有一个防抖效果

    6.useRef

    useRef 可以存储一个不需要渲染的值。
    与 state 的区别:ref 的改变不会渲染,state 会
    与普通对象的区别:ref 的值不会重置,普通对象会

    7.useImperativeHandle

    useImperativeHandle 配合 forwardRef 将子组件的 ref 传递给父组件。

    /**
     * @param { ref } ref:forWardRef 渲染函数中获得的第二个参数
     * @param { function } createHandle:处理函数,返回值作为暴露给父组件的 ref 对象
     * @param { array } dependencies:依赖项
     */
    useImperativeHandle(ref, createHandle, dependencies?)
    示例:
    
    // 子组件
    const Son = forwardRef((props, ref) => {
      const divRef = useRef(null)
      useImperativeHandle(ref, () => {
        return {
          sendData: () => {
            console.log(divRef.current)
          }
        }
      }, [])
      return <div ref={divRef}>子组件</div>
    })
    // 父组件
    function Parent() {
      const sonRef = useRef(null)
      return <Son ref={sonRef}></Son>
    }
    

    8.useMemo

    useMemo 在每次重新渲染的时候能够缓存计算的结果。

    /**
     * @param { function } calculateValue:要缓存计算值的函数,返回值作为缓存值
     * @param { array } dependencies:依赖项数组
     * @return { any } cachedValue:缓存值(calculateValue 返回的值)
     */
    const cachedValue = useMemo(calculateValue, dependencies)
    

    cachedValue 初次为不带参数调用 calculateValue 的返回值
    后续如果依赖项没有变,就返回上次缓存的值;否则将再次调用 calculateValue,并返回最新结果
    注意:应该仅仅把 useMemo 作为性能优化的手段

    9.useCallback

    /**
     * @param { function } fn:想要缓存的函数
     * @param { array } dependencies:依赖项数组
     * @return { function } cachedFn:缓存的函数
     */
    const cachedFn = useCallback(fn, dependencies)
    

    在初次渲染时,useCallback 返回你已经传入的 fn 函数
    在之后的渲染中, 如果依赖没有改变,useCallback 返回上一次渲染中缓存的 fn 函数;否则返回这一次渲染传入的 fn。
    注意:

    不应在循环或者条件语句中调用 useCallback
    应该仅仅把 useMemo 作为性能优化的手段

    相关文章

      网友评论

          本文标题:hooks

          本文链接:https://www.haomeiwen.com/subject/opvewdtx.html