我正在尝试构建一个与服务器通信以从数据库查询数据的React应用。我想在应用程序获取数据时显示加载消息。这是代码段:
class App extends React.Component {
constructor(props) {
super(props)
this.clickHandler = this.clickHandler.bind(this);
this.state = {
isLoading: false,
data: [],
content: ''
}
}
clickHandler() {
this.setState({ isLoading: true });
fetch('url_1')
.then(res => res.json())
.then(data => this.setState({ data: data }, () => {
this.getContentByData() // loading message vanished before content is displayed
}))
.then(() => this.setState({ isLoading: false }));
}
getContentByData() {
fetch(`url_2?data=${this.state.data}`)
.then(res => res.json())
.then(content => this.setState({ content: content }))
}
render() {
return (
<div>
{this.state.isLoading ? <h1>loading</h1>: null}
<h6>{this.state.content}</h6>
<button type="button" onClick={this.clickHandler}>Click Me!</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
在显示内容之前,加载消息消失了。我该如何解决?
答案 0 :(得分:1)
您可以将render
方法更改为如下形式:
render() {
let content = <Loader />;
if (!this.state.isLoading && this.state.content) {
content = (
<h6>{this.state.content}</h6>
<button type="button" onClick={this.clickHandler}>Click Me!</button>
)
}
return (
<div>
{content}
</div>
)
}
Loader
是您的加载程序组件。当然,它也可以是h1标题或您想要的任何内容。
答案 1 :(得分:0)
您需要像下面这样在getContentByData()处减轻负担。
getContentByData() {
fetch(`url_2?data=${this.state.data}`)
.then(res => res.json())
.then(content => this.setState({ content: content, isLoading : false }))
}
不要忘记在clickHandler()方法中删除isLoading = false。
答案 2 :(得分:0)
isLoading
将在getContentByData
内部完成提取之前设置为false,因为它不是clickHandler
中的promise链的一部分。
在isLoading
中完成提取后,您可以将getContentByData
设置为false。
class App extends React.Component {
state = {
isLoading: false,
data: [],
content: ""
};
clickHandler = () => {
this.setState({ isLoading: true });
fetch("url_1")
.then(res => res.json())
.then(data => this.setState({ data }, this.getContentByData));
};
getContentByData = () => {
fetch(`url_2?data=${this.state.data}`)
.then(res => res.json())
.then(content => this.setState({ isLoading: false, content }));
}
// ...
}
答案 3 :(得分:0)
甚至更好的是,您可以渲染如下内容:
render() {
return (
<div>
{this.state.isLoading && !this.state.content && <Loader />}
{!this.state.isLoading && this.state.content && (
<Fragment>
<h6>{this.state.content}</h6>
<button type="button" onClick={this.clickHandler}>Click Me!</button>}
</Fragment>)
</div>
)
}