我的 React 应用程序没有任何 API 调用,我希望在安装所有组件(包括所有子组件)时有一个加载页面。我的页面需要几秒钟才能加载。
我遇到的问题是我不想使用 setTimeout,因为我的页面可以加载任何秒数。我只想显示加载屏幕,直到我的实际页面准备好显示为止。
load
事件(假设您正在谈论 React hooks 实现。):-
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 */})
}
只需将纯CSS加载器添加到html文件的index.html即可。
此处工作沙箱代码: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>
我还添加了一些代码来计算组件树挂载时间。代码沙箱挂载了大约40万个元素,挂载整棵树需要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
);
ReactDOM.render 方法提供了一个回调,该回调在安装完成后触发。
ReactDOM.render(element, container[, callback])
您可以在这里做一些有趣的事情,例如添加或删除类/元素,甚至做更多的事情来显示良好的预加载用户体验。
但是要在安装之前显示某些内容,您只需在 div 中放入一些内容即可将反应树渲染到其中。一旦反应完成其渲染,该元素内的所有内容都将被替换。
const rootElement = document.getElementById("root");
ReactDOM.render(<MyAwesomeComponentTree />,rootElement);
<body>
<div id="root">
<!-- Everything here will be replaced by React -->
</div>
</body>
您可以在页面尚未准备好时设置加载程序。你只需要设置一个状态,比如:
const [isReady, setIsReady] = React.useState(false);
然后你可以做:
if(!isReady) {
return <>Loading...</>
}
return (
<>
{*/ your content here */}
</>
);
当您将
isReady
设置为 true 时,您的组件将使用页面内容重新呈现。
const [loading,setLoading] = useState(false);
//on button clicked
const handleDataComponent = ()=>{
setLoading(!loading);
}
return (
{loading &&
<div>{DataComponent here}</div>
}
)
import { useEffect, useState } from "react";
const App = () => {
const [isLoading, setIsLoading] = useState(true);
const handleLoading = () => {
setIsLoading((prevState) => !prevState);
};
useEffect(() => {
window.addEventListener("load", handleLoading);
// clean-up function
return () => window.removeEventListener("load", handleLoading);
}, []);
return <>{isLoading ? <LoadingUI /> : <ActualComponent />}</>;
};