简体   繁体   English

如何在我的所有组件都安装在 React 中之前有一个加载屏幕

[英]How to have a loading screen until all my components are mounted in React

I do not have any API calls for my react app, I want to have a loading page while all my components are being mounted (including all children).我的反应应用程序没有任何 API 调用,我希望在安装所有组件(包括所有子组件)时有一个加载页面。 My page does take few seconds to load.我的页面确实需要几秒钟才能加载。

The issue I am having is that I do not want to use setTimeout as my page can load for any amount of seconds.我遇到的问题是我不想使用 setTimeout,因为我的页面可以加载任意秒数。 I just want to show a loading screen until my actual page is ready to show.我只想显示一个加载屏幕,直到我的实际页面准备好显示。

Try the load event like so (assuming you're talking about react hooks implementation.):-像这样尝试load事件(假设您正在谈论反应挂钩的实现。):-

const Component = () => {
const [isLoading, setIsLoading] = React.useState(true);

const handleLoading = () => {
setIsLoading(false);
}

useEffect(()=>{
window.addEventListener("load",handleLoading);
return () => window.removeEventListener("load",handleLoading);
},[])

return !isLoading ? (
{*/ your content here */}
):({*/ your loader */})

}

Just add a pure CSS loader to your index.html of the html file.只需将纯 CSS 加载程序添加到 html 文件的 index.html 即可。

Working sandbox code here: https://codesandbox.io/s/silly-frog-z7ju3?file=/src/index.js:288-438此处的工作沙箱代码: https://codesandbox.io/s/silly-frog-z7ju3?file=/src/index.js:288-438

    <title>React App</title>
    <style>
      #root .loader-container {
        background-color: #0cbaba;
        background-image: linear-gradient(315deg, #0cbaba 0%, #380036 74%);
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      #root {
        /* display: none; */
      }
      .sk-chase {
        width: 40px;
        height: 40px;
        position: relative;
        animation: sk-chase 2.5s infinite linear both;
      }

      .sk-chase-dot {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        animation: sk-chase-dot 2s infinite ease-in-out both;
      }

      .sk-chase-dot:before {
        content: "";
        display: block;
        width: 25%;
        height: 25%;
        background-color: #fff;
        border-radius: 100%;
        animation: sk-chase-dot-before 2s infinite ease-in-out both;
      }

      .sk-chase-dot:nth-child(1) {
        animation-delay: -1.1s;
      }
      .sk-chase-dot:nth-child(2) {
        animation-delay: -1s;
      }
      .sk-chase-dot:nth-child(3) {
        animation-delay: -0.9s;
      }
      .sk-chase-dot:nth-child(4) {
        animation-delay: -0.8s;
      }
      .sk-chase-dot:nth-child(5) {
        animation-delay: -0.7s;
      }
      .sk-chase-dot:nth-child(6) {
        animation-delay: -0.6s;
      }
      .sk-chase-dot:nth-child(1):before {
        animation-delay: -1.1s;
      }
      .sk-chase-dot:nth-child(2):before {
        animation-delay: -1s;
      }
      .sk-chase-dot:nth-child(3):before {
        animation-delay: -0.9s;
      }
      .sk-chase-dot:nth-child(4):before {
        animation-delay: -0.8s;
      }
      .sk-chase-dot:nth-child(5):before {
        animation-delay: -0.7s;
      }
      .sk-chase-dot:nth-child(6):before {
        animation-delay: -0.6s;
      }

      @keyframes sk-chase {
        100% {
          transform: rotate(360deg);
        }
      }

      @keyframes sk-chase-dot {
        80%,
        100% {
          transform: rotate(360deg);
        }
      }

      @keyframes sk-chase-dot-before {
        50% {
          transform: scale(0.4);
        }
        100%,
        0% {
          transform: scale(1);
        }
      }
    </style>
  </head>

  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root">
      <div class="loader-container">
        <div class="loader">
          <div class="sk-chase">
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
          </div>
        </div>
      </div>
    </div>

 
  </body>
</html>

I have also added a little bit of code to calculate the component tree mount time.我还添加了一些代码来计算组件树的挂载时间。 The code sandbox mounts about 400,000 elements and it takes 3 seconds to mount the whole tree.代码沙箱挂载了大约 400,000 个元素,挂载整个树需要 3 秒。

const t0 = performance.now();

function renderCallback(e) {
  console.log("Rendering done?", e);
  const t1 = performance.now();

  console.log(`Mount took ~${(t1 - t0) / 1000} seconds.`);
}

const rootElement = document.getElementById("root");

ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement,
  renderCallback
);

A simple callback when rendering is completed渲染完成时的简单回调

The ReactDOM.render method provides a callback which fires after the mount has been completed. ReactDOM.render 方法提供了一个回调,该回调在挂载完成后触发。

ReactDOM.render(element, container[, callback])

You can do some interesting things here like add or remove classes/elements and do even more things to show good pre loading UX.你可以在这里做一些有趣的事情,比如添加或删除类/元素,并做更多的事情来展示良好的预加载用户体验。

Just show a static loader before the UI is mounted只需在安装 UI 之前显示 static 加载程序

But to just show something until mounted you just have to put something inside the div you will render the react tree into.但是要在安装之前显示一些东西,您只需在 div 中放置一些东西,您将渲染反应树。 Once react completes its render everything inside that element will be replaced.一旦 react 完成渲染,该元素内的所有内容都将被替换。

const rootElement = document.getElementById("root");
ReactDOM.render(<MyAwesomeComponentTree />,rootElement);

<body>
    <div id="root">
       <!-- Everything here will be replaced by React -->
    </div>
</body>

https://reactjs.org/docs/react-dom.html#render https://reactjs.org/docs/react-dom.html#render

You could just set a loader while your page isn't ready.您可以在页面尚未准备好时设置一个加载器。 You just need to set a state like:你只需要设置一个 state 像:

const [isReady, setIsReady] = React.useState(false);

And then you can do:然后你可以这样做:

if(!isReady) {
  return <>Loading...</>
}

return (
  <>
     {*/ your content here */}
  </>
);

When you will set your isReady to true, then your component will be rerendered with the content of your page.当您将isReady设置为 true 时,您的组件将使用页面内容重新呈现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM