React-在呈现获取的数据之前显示加载消息

时间:2019-04-24 07:22:31

标签: reactjs

我正在尝试构建一个与服务器通信以从数据库查询数据的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'))

在显示内容之前,加载消息消失了。我该如何解决?

4 个答案:

答案 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>
)
}