All files / src/_util use-visible-transition.ts

100% Statements 11/11
100% Branches 6/6
100% Functions 6/6
100% Lines 8/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43                          330x   330x     330x 293x   1x       330x   330x                       1x      
import { useState, useEffect, useRef } from "react";
 
export function useVisibleTransition(visible: boolean) {
  /**
   * visbile 和 contentIn 用于控制浮层渲染和动画,下面是两个状态组合的解释:
   *
   * state | visible | contentIn | 说明
   * ------|---------|-----------|-----------------------
   * 0     | false   | false     | 初始状态,浮层不渲染,如果 visible 变为 true,则进入 state 1
   * 1     | true    | false     | 浮层渲染,淡入动画还没开始,浮层不可见。会自动进入 state 2
   * 2     | true    | true      | 浮层渲染,淡入动画开始,如果 visible 变为 false,则进入 state 3
   * 3     | false   | true      | 浮层渲染,淡出动画开始,动画结束后,回到 state 0
   */
  const [contentIn, setContentIn] = useState(visible);
 
  const timerRef = useRef(null);
 
  // visible 变为 true 的时候,让动画进入
  useEffect(() => {
    if (visible) {
      // 这里 setTimeout() 是为了解决 IE11 下动画出现异常的问题
      timerRef.current = setTimeout(() => setContentIn(true), 0);
    }
  }, [visible]);
 
  useEffect(() => () => clearTimeout(timerRef.current), []);
 
  return {
    /**
     * 内容是否应该渲染
     */
    shouldContentRender: visible || contentIn,
    /**
     * 内容是否应该显示
     */
    shouldContentEnter: visible && contentIn,
    /**
     * 内容退出完成后回调
     */
    onContentExit: () => setContentIn(false),
  };
}