在登陆页面中显示和隐藏加载器,而无需在 react 中调用 api 调用或设置超时?



我在react应用程序中的某个地方遇到了redux问题,搜索了很多,但没有找到想要的解决方案,这就是我在这里发布这个问题的原因,所以我的问题是,当页面加载时,我必须显示一个加载程序,当整个HTML加载程序应该隐藏时,下面是我的代码

class LoginScreen extends React.Component {
state = {
email: '',
password: '',
stayLoggedIn: false,
isLoading: true
};
componentDidMount() {
setTimeout(() => {
this.setState({ isLoading: false });
}, 2000);
}

渲染基于isLoading的html,但目前我已经使用了设置超时显示和隐藏加载程序,我想知道有没有任何解决方案可以让它在没有设置超时的情况下工作,任何帮助都是值得的。

如果我做对了"当整个HTML加载时",你想在浏览器中呈现react应用程序时显示一个加载程序。为此,你可以做的是:

1-如果你已经用Create React App启动了你的项目-转到公用文件夹,有一个名为index.html的文件-它将有一个<div>元素,您的整个react应用程序将由web捆绑器呈现到该元素中,在这种情况下,它将是webpack。-在这个div内部编写一个类似的加载程序

<div id="root">
<section class="loader">
<h1 class="heading">INITIALIZING</h1>
<p class="sub-heading">bear with us ...</p>
</section>
</div>

所以这里发生的事情是当你写下这段代码

ReactDOM.render(<App />, document.getElementById('root'));

它基本上将您的react应用程序注入到这个根文档元素中,一旦您的应用程序捆绑在一起,整个html就会加载到浏览器中并注入到这个div中,它将取代您的加载程序,您的登录页面将可见

这是加载程序动画的CSS

<style>
.loader {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
background-color: #fff;
color: #000;
overflow-y: hidden;
}
.loader .heading {
font-size: 36px;
text-align: center;
animation: heart-beat 4s infinite ease-in;
z-index: 1;
}
.loader .sub-heading {
font-size: 18px;
text-align: center;
color: #4b4b4b;
z-index: 1;
}
@keyframes heart-beat {
0% {
opacity: 0.1;
}
50% {
opacity: 1;
}
100% {
opacity: 0.1;
}
}
</style>

2-第二种选择是在没有CRA的情况下创建react应用程序,但在这种情况下,您将再次获得index.html,您可以重复上述步骤。

  1. setTimeout只是一个异步操作,当您调用setState函数时,React会比较旧状态和新状态,并根据新状态触发对组件的渲染。

  2. 当你的组件有一个本地状态时,你将redux状态作为道具注入到你的组件中,这样当你有本地状态时就不会触发渲染,你需要使用componentWillReceiveProps方法并调用setState方法,通过使用基于新道具的setState来更改你的本地状态。

    注:componentWillReceiveProps方法工作至React v17

import React from "react";
import ReactDOM from "react-dom";
const delay = async ms => await new Promise(resolve => setTimeout(resolve, ms));
class Loader extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false
};
}
componentWillReceiveProps(nextProps) {
this.setState({ isLoading: nextProps.isLoading });
}
render() {
return (
<div style={{ border: "1px solid #999", padding: "10px" }}>
Loader component
<div>Loading: {String(this.state.isLoading)}</div>
</div>
);
}
}
class LoginScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false
};
}
async asyncOperation() {
// Show loader
this.setState({ isLoading: true });
// Async operation, like fetch, etc...
await delay(1000);
// Hide loader
this.setState({ isLoading: false });
}
render() {
return (
<div>
<Loader isLoading={this.state.isLoading} />
<br />
<button
onClick={this.asyncOperation.bind(this)}
disabled={this.state.isLoading}
>
{this.state.isLoading ? "Waiting..." : "Call async operation"}
</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<LoginScreen />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

最新更新