javascript - 使用 HOC 加载程序时的重新渲染问题

标签 javascript reactjs redux immutable.js higher-order-components

我正在构建一个应用程序,其中有大量页面,每个页面都需要加载器图标来显示数据何时来自服务器但尚未到达,但如果根本没有数据,则不会显示任何内容。我可以在不使用高阶组件(HOC)的情况下毫无问题地展示这一点,但在每个组件中这样做是乏味的。我希望加载器代码是可重用的,以便我可以在每个需要的地方使用它。但我面临着这个问题。

If there is data, there is no issue. If there is no data at all, then the loader keeps loading and loading instead should show no content.

我必须在 componentDidMount 中使用 if (!this.props.size) 来获取数据,因为如果我不这样做,组件将不断重新渲染,如果我这样做,如果有数据,组件不会重新渲染,但如果根本没有数据,组件会不断重新渲染,并显示加载图标。

这是代码

class Logs extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      show: false,
    };
  }
  componentDidMount() {
    // this.props.requestLogs();
    if (!this.props.logs.size) {
      this.props.requestLogs();
    }
  }

  //componentWillUnmount() {
    //document.body.removeEventListener("", this.props.requestLogs());
  //}


  renderLogs() {
    const { logs } = this.props;
    return logs.size > 0
      ? logs.valueSeq().map(log => {
          return (
            <div className="card" key={log.get("_id")}>
              <li className="row">
                <div className="col-md-6">
                  <a
                    onClick={() =>
                      this.handleDialog(log.get("_id"), log.get("error_stack"))}
                  >
                    {log.get("error_message")}
                  </a>
                </div>
                <div className="col-md-6 text-right">
                  <a
                    className="text-danger"
                    onClick={() => this.handleDelete(log.get("_id"))}
                  >
                    Delete
                  </a>
                </div>
              </li>
            </div>
          );
        })
      : <p>No Content</p>;
  }
  render() {
    const { logs, isRequesting } = this.props;
    return (
      <div className="container">
        <div className="row mg-btm-md">
          <div className="col-xs-6"> <h1>Logs</h1></div>
        </div>
        <ul className="list-group">
          {this.renderLogs()}
          {this.state.show ? this.props.dialog : null}
        </ul>
      </div>
    );
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(
  Loader("isRequesting")(Logs)
);


const Loader = prop => WrappedComponent => {
  return class Loader extends React.PureComponent {
    render() {
      return this.props[prop]
        ? <div className="earth-spinning">
            <img
              src={EarthSpinning}
              alt="spinner"
              style={{ margin: "0 auto" }}
            />
          </div>
        : <WrappedComponent {...this.props} />;
    }
  };
};

export default Loader;

完整代码在这里https://gist.github.com/SanskarSans/b30c085ffacf01c58b66f128096746cc

最佳答案

我做了一些非常简单的事情,肯定还有需要改进的地方。 但它解决了您想要的问题,如果您有“loadedData”标志,您将显示数据,如果没有,您将显示加载程序。

代码链接: https://codepen.io/tzookb/pen/VWdeyE

代码:

class SomeComponent extends React.Component {
  render() {
    return <div>Im a basic component</div>;
  }
}

function withLoader(WrappedComponent) {
  return class extends React.Component {
    render() {
      if (this.props.loadedData) {
        return <WrappedComponent {...this.props} />;        
      } else {
        return <h1>Loading...</h1>;
      }
    }
  };
}

let SomeComponentWithLoader = withLoader(SomeComponent);


ReactDOM.render(<SomeComponentWithLoader loadedData={false} />, document.getElementById("app"));

关于javascript - 使用 HOC 加载程序时的重新渲染问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44895561/

相关文章:

javascript - 每当用户使用自定义用户 uid 在 firebase 中注册时,如何上传文档?

javascript - React 正在将旧状态发送给它的父级

javascript - 我是否总是需要从 redux 中间件返回一个值?

reactjs - 在mapStateToProps之后接下来会调用什么

reactjs - 如何更新react-redux中的存储状态?

javascript - AngularJS ng-fab-form 的服务器错误

javascript - 在 Accept Hosted 方法中将 showReceipt 设置为 false 时没有事务响应 (Authorize.net)

javascript - 在 ReactJS 中访问文件之间的状态

javascript - 将绑定(bind)函数 react 到数组中的每个项目

javascript - Redux 订阅了整个状态