【问题标题】:How to use react transition group after API loads?API加载后如何使用反应过渡组?
【发布时间】:2022-02-12 18:08:44
【问题描述】:
  1. 当页面加载时,我正在显示一个骨架加载器。
  2. 当我的 API 完成获取后,骨架会从 DOM 中移除
  3. 内容已添加到 DOM。

我想在骨架消失时淡出,在内容进入时淡入。

为此,我使用了带有 CSSTransition 组件的 react-transition-group。

到目前为止,这是我的代码的简化版本,请原谅我缺少 codepen,因为复制和模仿 API 加载/就绪状态对我来说非常乏味:

Homepage.tsx:

function HomePage() {
 
  const { data: dataAPI, error } = useAPI1();
  const { data: dataAPI2, error: error2 } = useAPI2();
  
  if (!dataAPI || !dataAPI2) return <SkeletonLoader isLoading={!dataAPI && !dataAPI2} />;

  if (error) return <Error customMessage="Error from API1" />;
  if (error2) return <Error customMessage="Error from API2" />;

  return (
    <>
      <p>My content !</p>
    </>
  );
}

export default HomePage;

SkeletonLoader.tsx

const SkeletonLoader = ({ isLoading }: { isLoading: boolean }) => {
  const nodeRef = useRef(null);
  return (
    <CSSTransition timeout={1000} classNames="skeleton" in={!isLoading} nodeRef={nodeRef}>
      <Layout>
        <div className={styles.skeleton} ref={nodeRef}>
          <div className={styles.img} />
          <div className={styles.line} />
          <SkeletonProduct />
          <SkeletonProduct />
          <SkeletonProduct />
        </div>
      </Layout>
    </CSSTransition>
  );
};

export default SkeletonLoader;

global.scss

.skeleton-enter {
  opacity: 0;
}

.skeleton-enter-active {
  opacity: 1;
  transform: translateX(0);
  transition: opacity 1000ms;
}

.skeleton-exit {
  opacity: 1;
}

.skeleton-exit-active {
  opacity: 0;
  transition: opacity 1000ms;
}

我尝试了不同的方法,但是当从 DOM 中移除骨架时,我看不到淡出。

感谢您的帮助。

【问题讨论】:

    标签: reactjs css-transitions react-transition-group


    【解决方案1】:

    您在过渡组有时间播放动画之前卸载它。

      if (!dataAPI || !dataAPI2) return <SkeletonLoader isLoading={!dataAPI && !dataAPI2} />;
    

    将停止渲染您的过渡组。

    您可以尝试始终渲染过渡组,并使用 'unmountOnExit` 属性将其自行卸载:

    function HomePage() {
      const { data: dataAPI, error } = useAPI1();
      const { data: dataAPI2, error: error2 } = useAPI2();
      
      const isLoading =  (!dataAPI || !dataAPI2) 
      const shouldRenderContent = !error && !error2 && !isLoading;
    
      return (
        <>
          { error && <Error customMessage="Error from API1" /> }
          { error2 && <Error customMessage="Error from API2" /> }
          { isLoading && <SkeletonLoader isLoading={isLoading} />}     
          {shouldRenderContent && <p>My content !</p> }
        </>
      );
    }
    
    export default HomePage;
    
    ....
        <CSSTransition 
           unmountOnExit  // <-- this will remove the children when 'exit' ran.
           timeout={1000}
           classNames="skeleton"
           in={!isLoading}
           nodeRef={nodeRef}
           >
    .....
    
    

    Code sandbox api 调用被简单的按钮切换替换

    【讨论】:

    • 感谢您的帮助!那是我的错,因为我没有分享完整的代码,但是在我返回之前我有几个变量是由我的 API 调用中的数据初始化的。这意味着我不能有一个包含所有加载、错误和成功案例的返回语句,因为应用程序将在到达该语句之前崩溃。正如你所说的那样,我在它有时间转换之前卸载了组件,所以我可能会尝试另一种方法:stackoverflow.com/a/54114180/7354466
    • @RebootGG ,干杯,我希望我的回答无论如何都有帮助。我无法准确评估我没见过的代码,所以请谨慎对待我的下一个建议;我会小心添加那个钩子。听起来你正在通过更复杂的创可贴来解决这个问题。我认为您的目标应该是降低复杂性,IE 将数据使用隐藏在单独的钩子/useMemo 中并将其拆分为更多子组件。
    猜你喜欢
    • 2018-04-26
    • 2021-10-17
    • 2017-10-07
    • 2020-09-19
    • 2018-01-26
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 2021-03-06
    相关资源
    最近更新 更多