当我的React组件通过AJAX获取时显示加载微调器/ gif的最佳方法?

use*_*003 6 javascript ajax reactjs

想象一下,我有一个非常简单的React组件,它显示了存储的元素列表this.state.myList(参见下面的示例)

点击底部的"刷新"按钮会使React查询后端服务器并检索随后将显示的更新列表.该列表的实际内容或实现是无关紧要的.

var Foo = React.createClass({
  handleButtonClick: function() {
    return $.ajax({
      type: "POST",
      url: "/some/refresh/url",
      data: JSON.stringify({}),
      dataType: "json",
      contentType: "application/json",
      success: (function(response){
        self.setState({ myList: response.list });
      })
    });
  },

  render: function() {
    return (
      <div className="container">
        <ul>
          {
            this.state.myList.map(function(item) {
              return <li id="{item.id}">{item.name}</li>
            });
          }
        </ul>

        <input type="submit" value="REFRESH LIST" onClick={this.handleButtonClick} />
      </div>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)

假设AJAX调用(无论出于何种原因)需要几秒钟.在此期间,我希望展示一个标准的"加载"或"旋转器"gif,让用户知道它正在工作.

在这里做到这一点的最佳方法是什么?

  • 在AJAX调用之前,我可以手动更新DOM并插入一个微调器gif,但这似乎不是"React方式".而且我不知道对反应维持的ReactDOM会产生什么影响.

  • 我可以跟踪状态isLoading并显示微调器,而不是列表,如果它正在加载.但后来我需要它render(),然后立即启动另一个AJAX动作调用.

任何帮助赞赏.

谢谢!

Tom*_*Tom 12

我总是解决这个问题的方法是让组件跟踪fetchInProgress其状态.

在进行提取之前,将此值设置为true; 当提取完成(成功或失败)时,将值设置回false.

然后组件的render方法尊重这个标志; 如果是标志true,则呈现微调器而不是数据集.

var Foo = React.createClass({
    handleButtonClick: function() {

        // before making call, set fetch flag
        self.setState({ fetchInProgress: true });

        return $.ajax({
            type: "POST",
            url: "/some/refresh/url",
            data: JSON.stringify({}),
            dataType: "json",
            contentType: "application/json",
            success: (function(response) {
                // when updating with dataset, also reset fetch flag
                self.setState({
                    fetchInProgress: false,
                    myList: response.list
                });
            }),
            failure: ((function(reason) {
                // make sure to reset even if fetch fails!
                self.setState({
                    fetchInProgress: false
                });
            })
        });
    },

    render: function() {
        return (
            <div className="container">
                <ul>
                    {
                        this.state.fetchInProgress
                            : <Spinner />
                            : this.state.myList.map(function(item) {
                                    return <li id="{item.id}">{item.name}</li>
                                })
                    }
                </ul>

                <input type="submit" value="REFRESH LIST" onClick={this.handleButtonClick} />
            </div>
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 这种方法非常适合简单的场景,我们创建了一个辅助库来避免手动切换 fetchInProgress 标志,并处理从多个地方发起的多个请求,希望对您有所帮助:https://github.com/Lemoncode/react-promise-跟踪有关其工作原理的帖子:https://www.basefactor.com/react-how-to-display-a-loading-indicator-on-fetch-calls (4认同)