记录一些工作中的常用的自定义hook

  1. useUnmountedRef: 用于判断是否首次渲染
import { useRef, useEffect } from 'react'

const useUnmountedRef = () => {
  const unmountedRef = useRef(false)
  useEffect(() => {
    return () => {
      unmountedRef.current = true
    }
  }, [])
  return unmountedRef
}

export default useUnmountedRef
  1. useState的进阶版本,当首次渲染的时候不改变state中的值
import { useState, Dispatch, SetStateAction, useCallback } from 'react'
import useUnmountedRef from './useUnmountedRef'

function useSafeState(initialState?: any) {
  const unmountedRef = useUnmountedRef()
  const [state, setState] = useState(initialState)
  const setCurrentState = useCallback((currentState: any) => {
    /** don't invoke setState if component is unmounted */
    if (unmountedRef.current) return
    setState(currentState)
  }, [])

  return [state, setCurrentState] as const
}

export default useSafeState

  1. useState的进阶版本,此hook中state的值只会被改变一次
import { useCallback, useRef, useState } from 'react'

export default function useStateOnce(initValue: T): [T, (newValue: T) => void] {
  const updatedRef = useRef(false)
  const [value, setState] = useState(initValue)
  const setStateOnce = useCallback((newValue: T) => {
    if (!updatedRef.current) {
      updatedRef.current = true
      setState(newValue)
    }
  }, [])

  return [value, setStateOnce]
}

4.useValueChange:此hook业务中非常常用,传入两个参数callback以及value,该hook依赖value,如果value从无到有或者值发生改变则调用callback函数

import { useRef, useEffect } from 'react'

export default function useValueChange(cb: () => void, value: T) {
  const prevValueRef = useRef(null)
  useEffect(() => {
    if (prevValueRef.current !== null && prevValueRef.current !== value) {
      cb()
    }
    prevValueRef.current = value
  }, [value])
}

  1. useAsync:一个运行函数的状态机,给予一个异步函数loading,error等状态
import { useRef, useCallback } from 'react'

import useSafeState from './useSafeState'

export default function useAsync(func: (...args: any[]) => any, handleError?: (e: any) => any) {
  const [data, setData] = useSafeState(null)
  const [loading, setLoading] = useSafeState(false)
  const [error, setError] = useSafeState(null)
  const funcRef = useRef(func)
  funcRef.current = func
  const handleErrorRef = useRef(handleError)
  handleErrorRef.current = handleError

  const run = useCallback(async (...params: any[]) => {
    setError(null)
    setLoading(true)

    try {
      const data = await funcRef.current(...params)
      setData(data)
      return data
    } catch (e) {
      setError(e as Error)
      if (handleErrorRef.current) {
        handleErrorRef.current(e)
      }
    } finally {
      setLoading(false)
    }
  }, [])

  const reset = useCallback(() => {
    setData(null)
    setLoading(false)
    setError(null)
  }, [])

  return {
    run,
    loading,
    error,
    data,
    reset
  }
}

6.useConfirmDialog:一个用于自定义弹出框的hook,该hook只会返回true or false

export default function useConfirmDialog() {
  const containerRef = useRef()
  const { t } = useTranslation('common') //此为i-18n的国际化hook,可去除

  const openModal = useCallback(
    ({
      title,
      content,
      onConfirm,
      onCancel,
      confirmLabel,
      cancelLabel,
      hideCancelButton = false
    }: IConfirmDialogConfigs) => {
      const div = document.createElement('div')
      div.setAttribute('id', 'confirm-modal-container')
      document.body.appendChild(div)

      const closeModal = () => {
        const unmountResult = ReactDOM.unmountComponentAtNode(div)
        if (unmountResult && div.parentNode) {
          div.parentNode.removeChild(div)
        }
      }

      const handleConfirm = async () => {
        await onConfirm(closeModal)
      }
      const handleCancel = async () => {
        closeModal()
        if (onCancel) {
          onCancel()
        }
      }
      containerRef.current = div
      ReactDOM.render(
        
          {content}
          
            {onCancel && !hideCancelButton && (
              
                {cancelLabel || t('button.cancel')}
              
            )}
            {onConfirm && {confirmLabel || t('button.confirm')}}
          
        ,
        div
      )
    },
    [containerRef, t]
  )
  return openModal
}

你可能感兴趣的:(记录一些工作中的常用的自定义hook)