1

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

如果有数据,就没有问题。如果根本没有数据,那么加载器会继续加载并且加载应该不显示任何内容。

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

这是代码

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

4

1 回答 1

0

我做了一些超级简单的事情,肯定有需要改进的地方。但它解决了您想要的问题,如果您有“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"));
于 2017-07-04T18:40:12.817 回答