React Hook~部分实用钩子

useCompareEffect

/**
 * useCompareEffect
 * useEffect只是普通的浅比较,这里做了深比较
 * useEffect的依赖是否相同,相同不触发
 */
import { useEffect, useRef } from 'react'
import { isEqual } from 'lodash'

export default function useCompareEffect(effect: React.EffectCallback, dependencies?: Object) {
  function deepCompareDependencies(value: any) {
    const ref = useRef()

    if (!isEqual(value, ref.current)) {
      ref.current = value
    }

    return ref.current
  }

  useEffect(effect, deepCompareDependencies(dependencies))
}

useDependencyEffect

/**
 * 组件 componentDidMount 的时候不执行 useEffect 的方法
 * 只有依赖变化的时候会执行
 */
import { useRef, useEffect } from 'react'

export default function useDependencyEffect(effect: React.EffectCallback, dependencies: any[]) {
  const componentDidMount = useRef<boolean>(false)

  useEffect(() => {
    if (componentDidMount.current) {
      effect()
    }
  }, dependencies)

  /**
   * 必须放在最底下
   */
  useEffect(() => {
    componentDidMount.current = true
  }, [])
}

react不支持useState回调,建议采用useEffect,这里做了个useState的回调


/** useStateCallback setstate回调 */
export function useStateCallback<T>(initialState: T | (() => T)): [T, DispatchWithCallback<SetStateAction<T>>] {
  const [state, _setState] = useState(initialState);

  const callbackRef = useRef<Callback<T>>();
  const isFirstCallbackCall = useRef<boolean>(true);

  const setState = useCallback((setStateAction: SetStateAction<T>, callback?: Callback<T>): void => {
    callbackRef.current = callback;
    _setState(setStateAction);
  }, []);

  useEffect(() => {
    if (isFirstCallbackCall.current) {
      isFirstCallbackCall.current = false;
      return;
    }
    callbackRef.current?.(state);
  }, [state]);

  return [state, setState];
}

// 使用: const [state, setstate] = useStateCallback()

基于ant4 prompt优化

/**
 * 离开页面prompt
 */
import React, { SetStateAction, useMemo, useState, useCallback, useRef, useEffect, ReactNode } from 'react'
import { Prompt, useHistory } from 'umi';
import { Modal } from 'antd';

type Callback<T> = (value?: T) => void;
type DispatchWithCallback<T> = (value: T, callback?: Callback<T>) => void;

/** useStateCallback setstate回调 */
export function useStateCallback<T>(initialState: T | (() => T)): [T, DispatchWithCallback<SetStateAction<T>>] {
  const [state, _setState] = useState(initialState);

  const callbackRef = useRef<Callback<T>>();
  const isFirstCallbackCall = useRef<boolean>(true);

  const setState = useCallback((setStateAction: SetStateAction<T>, callback?: Callback<T>): void => {
    callbackRef.current = callback;
    _setState(setStateAction);
  }, []);

  useEffect(() => {
    if (isFirstCallbackCall.current) {
      isFirstCallbackCall.current = false;
      return;
    }
    callbackRef.current?.(state);
  }, [state]);

  return [state, setState];
}

interface Iprops {
  isPrompt: boolean
  content?: string
}

export default function UsePrompt(props: Iprops) {
  const [promptStatus, setpromptStatus] = useStateCallback(props.isPrompt)
  const history = useHistory()
  useEffect(() => {
    setpromptStatus(props.isPrompt)
  }, [props.isPrompt])

  return (<>
    <Prompt
      when={promptStatus}
      message={location => {

        Modal.confirm({
          title: '提示',
          content: props.content || '确认离开吗?系统可能不会保存当前表单',
          okText: '确认',
          cancelText: '取消',
          onOk: () => {
            setpromptStatus(false, () => {
              history.push(location.pathname)
              return false
            })
          }
        });
        return false;
      }}
    />
  </>)
}
原文地址:https://www.cnblogs.com/mapleChain/p/12996510.html