Javascript 使用HOC for loader时重新呈现问题

Javascript 使用HOC for loader时重新呈现问题,javascript,reactjs,redux,immutable.js,higher-order-components,Javascript,Reactjs,Redux,Immutable.js,Higher Order Components,我正在构建一个应用程序,其中有大量页面,每个页面都需要加载器图标来显示何时数据来自服务器但尚未到达,但如果根本没有数据,则不会显示任何内容。我可以在不使用高阶组件(HOC)的情况下展示这一点,但在每个组件中这样做都很乏味。我希望加载程序代码是可重用的,这样我就可以在任何需要的组件中使用它。但我面临着这个问题 如果有数据,就没有问题。如果根本没有数据,那么 加载程序继续加载,而加载时不应显示任何内容 我必须在componentDidMount中使用if(!this.props.size)来获取数据

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

如果有数据,就没有问题。如果根本没有数据,那么 加载程序继续加载,而加载时不应显示任何内容

我必须在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;
类日志扩展了React.PureComponent{
建造师(道具){
超级(道具);
此.state={
秀:假,,
};
}
componentDidMount(){
//this.props.requestLogs();
如果(!this.props.logs.size){
this.props.requestLogs();
}
}
//组件将卸载(){
//document.body.removeEventListener(“,this.props.requestLogs()”);
//}
renderLogs(){
const{logs}=this.props;
返回日志。大小>0
?logs.valueSeq().map(log=>{
返回(
  • this.handleDialog(log.get(“\u id”)、log.get(“error\u stack”)} > {log.get(“错误消息”)} this.handleDelete(log.get(“\u id”))} > 删除
  • ); }) :无内容

    ; } render(){ const{logs,isRequesting}=this.props; 返回( 日志
      {this.renderLogs()} {this.state.show?this.props.dialog:null}
    ); } } 导出默认连接(MapStateTrops、mapDispatchToProps)( 加载程序(“isRequesting”)(日志) ); 常量加载器=prop=>WrappedComponent=>{ 返回类加载器扩展了React.PureComponent{ render(){ 归还这个。道具[道具] ? : ; } }; }; 导出默认加载程序;

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

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

    链接到代码:

    代码:

    类SomeComponent扩展React.Component{
    render(){
    返回一个基本组件;
    }
    }
    带加载器的函数(WrappedComponent){
    返回类扩展了React.Component{
    render(){
    如果(此.props.loadedData){
    返回;
    }否则{
    返回装载。。。;
    }
    }
    };
    }
    让SomeComponentWithLoader=withLoader(SomeComponent);
    ReactDOM.render(,document.getElementById(“app”);
    
    我做了一件非常简单的事情,当然还有改进的地方。 但它解决了您想要的问题,如果您有一个“loadedData”标志,则显示数据,如果没有,则显示加载程序

    链接到代码:

    代码:

    类SomeComponent扩展React.Component{
    render(){
    返回一个基本组件;
    }
    }
    带加载器的函数(WrappedComponent){
    返回类扩展了React.Component{
    render(){
    如果(此.props.loadedData){
    返回;
    }否则{
    返回装载。。。;
    }
    }
    };
    }
    让SomeComponentWithLoader=withLoader(SomeComponent);
    ReactDOM.render(,document.getElementById(“app”);
    
    显示“mapStateToProps”函数,我看不到您的“isRequesting”变量…我不知道您为什么对这样一个组件如此复杂。首先简化你的代码。你能告诉我应该在哪里改进吗?问题出在componentDidMount,我想,但无法解决问题。我将添加一个示例,说明我将如何改进,这与redux或其他软件无关。您应该安装两个工作正常的组件。在添加reduxshow“mapStateToProps”函数之后,我看不到您的“isRequesting”变量…我不知道您为什么对这样一个组件如此复杂。首先简化你的代码。你能告诉我应该在哪里改进吗?问题出在componentDidMount,我想,但无法解决问题。我将添加一个示例,说明我将如何改进,这与redux或其他软件无关。您应该安装两个工作正常的组件。然后添加redux
    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"));