有没有办法使用 React suspense 为回退组件应用淡入/淡出过渡?

gui*_*732 12 reactjs material-ui react-router-dom react-suspense

我有一个使用 MUI 的 React 应用程序,现在我已经使用微调器实现了悬念,它在加载内容时作为后备组件启动。我很想为回退组件添加淡入/淡出过渡,因为目前这种变化太突然了。

我的设置(对于这个特定问题的相关部分)如下:

依赖关系

    "@glidejs/glide": "^3.4.1",
    "@material-ui/core": "4.8.3",
    "@material-ui/icons": "4.5.1",
    "@material-ui/lab": "4.0.0-alpha.39",
    "@material-ui/pickers": "3.2.10",
    "@types/autosuggest-highlight": "^3.1.0",
    "@types/jest": "^24.0.0",
    "@types/node": "^12.0.0",
    "@types/react": "^16.9.0",
    "@types/react-dom": "^16.9.0",
    "@types/react-redux": "^7.1.7",
    "autosuggest-highlight": "^3.1.1",
    "connected-react-router": "^6.8.0",
    "history": "^4.10.1",
    "node-sass": "^4.13.0",
    "react": "^16.12.0",
    "react-date-picker": "^8.0.0",
    "react-dom": "^16.12.0",
    "react-feather": "^2.0.3",
    "react-redux": "^7.2.0",
    "react-router-dom": "^5.1.2",
    "react-scripts": "3.3.0",
    "redux-devtools-extension": "^2.13.8",
    "redux-ducks-ts": "^1.0.9",
    "redux-logger": "^3.0.6",
    "redux-saga": "^1.1.3",
    "reselect": "^4.0.0",
    "styled-components": "^4.4.1",
    "typescript": "~3.7.2"
Run Code Online (Sandbox Code Playgroud)

路由器块

这是应用程序的主要路由器,它有一个RouteWithSubRoutes组件接收路由作为参数并渲染react-render-dom路由组件,但基本上充当路由器切换容器

import React, { FC, Suspense } from "react";
import { Switch } from "react-router-dom";
import routes from "./routes";
import { Route, Redirect } from "react-router-dom";
import { SessionContainerProps } from "./types";

// Coponents
import RouteWithSubRoutes from "components/_shared/RouteWithSubRoutes";
import Footer from "components/_shared/Footer";
import SuspenseLoader from "components/_shared/SuspenseLoader";

const SessionContainer: FC<SessionContainerProps> = () => (
    <>
        <Suspense fallback={<SuspenseLoader />}>
            <Switch>
                {routes.map((route, i) => (
                    <RouteWithSubRoutes key={`${i}_${route.path}`} {...route} />
                ))}
                <Route path="/login/*">
                    <Redirect to="/login" />
                </Route>
            </Switch>
        </Suspense>
        <Footer />
    </>
);

export default SessionContainer;

Run Code Online (Sandbox Code Playgroud)

SuspenseLoader 组件细节

现在它是一个居中的 MUI 循环进度(Spinner),带有覆盖整个应用程序的白色背景

import React from "react";
import { CircularProgress } from "@material-ui/core";

const SuspenseLoader = () => {
    return (
        <div
            style={{
                position: "fixed",
                top: 0,
                left: 0,
                width: "100vw",
                height: "100vh",
                zIndex: 10000,
                backgroundColor: "#FFF",
                display: "flex",
                alignItems: "center",
                flexDirection: "column",
                justifyContent: "center",
                marginTop: "auto",
                marginBottom: "auto",
            }}
        >
            <CircularProgress
                size="6rem"
                style={{
                    color: "#e8eaef",
                    margin: 0,
                    padding: 0,
                }}
            />
        </div>
    );
};
export default SuspenseLoader;

Run Code Online (Sandbox Code Playgroud)

小智 2

我会尝试尝试一下这个答案。我想你必须使用一些东西。

您可能想要使用 CSS 过渡:

.suspenseComponent {
  opacity: 1;
  transition: opacity 1s;
}

.fade {
  opacity: 0;
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您稍后更改元素的不透明度,它将在 1 秒的时间内发生。

然后您还需要 useRef (我认为),以便您可以跟踪该组件并手动更新不透明度。

import {useRef} from 'react'

const element = useRef(null)

...

<SuspenseComponent ref={element}/>

...

element.current.classList.add('fade')

// essentially the same thing as document.getElementById('suspense').classList.add('fade')
Run Code Online (Sandbox Code Playgroud)

使用上面的内容,您可以获得对元素的引用,并且可以向其添加或删除类,以便向其添加淡入淡出类。

最后你可以使用:

import {useEffect} from 'react'

const Example = () => {
  useEffect(() => {
    // anything here will execute on component mount

    return () => {
      // anything you return here will execute on component unmount
    }
  }, [])
}
Run Code Online (Sandbox Code Playgroud)

我没有自己构建它,但我认为您应该能够在组件安装上应用不透明度类,以便它在 1 秒内转换,然后在 useEffect 卸载上,如果您删除该类,它应该在 1 秒内转换出来。

如果它立即重新加载组件,那么也许您还可以包括:

setTimeout(() => {
  // delay whatever is refreshing the page
}, 1000)
Run Code Online (Sandbox Code Playgroud)

如果这可能有帮助的话。

希望这些想法的结合能帮助你有所收获。