显示基于另一个组件生命周期的组件

时间:2018-02-28 16:54:14

标签: javascript reactjs redux material-ui

我最近遇到了一个关于使用其中一个costum组件的问题。我为我正在进行的项目创建了一个“Chargement”(正在加载法语)组件。

此组件是一个带有深色背景的简单圆形微调器,在显示时会通知用户正在进行操作。

import React, {Fragment} from 'react';
import { CircularProgress } from 'material-ui/Progress';
import blue from 'material-ui/colors/blue';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';

const styles = theme => ({
  chargement: {
    position: 'fixed',
    left: '50%',
    top: '50%',
    zIndex: 1
  }
});

class Chargement extends React.Component {
  render () {
    const { classes } = this.props;
    if (this.props.chargement) {
      return (
        <Fragment>
          <div className='loadingicon'>
            <CircularProgress size={80} style={{ color: blue[500] }}/>
          </div>
          <div className='loadingBackground'/>
        </Fragment>
      );
    } else {
      return null;
    }
  }
}

const mapStateToProps = (state) => {
  return {
    chargement: state.App.chargement
  };
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({
  }, dispatch);
};

Chargement.propTypes = {
  classes: PropTypes.object.isRequired
};

let ChargementWrapped = withStyles(styles)(Chargement);
export default connect(mapStateToProps, mapDispatchToProps)(ChargementWrapped);

此组件基于我的redux商店中名为“chargement”的布尔变量显示。

每当我使用它来进行api调用和加载数据时,它就像一个魅力。但是,我的Web App中的一个组件需要相当长的时间来渲染(1-2秒)。该组件使用扩展面板呈现相当大的数据列表。我尝试根据componentWillMount和componentDidMount函数设置我的显示变量。

class ListView extends React.Component {
  componentWillMount () {
    this.props.setChargement(true);
  }
  componentDidMount () {
    this.props.setChargement(false);
  }

然而,在这种特殊情况下,“充电”组件永远不会显示。

我还尝试创建一个“包装组件”,以防问题来自我的“收费”组件,它与作为孩子的重新渲染组件有些相关。 :

export default class AppWrapper extends React.Component {
  render () {
    return (
      <Fragment>
        <Reboot />
        <EnTete />
        <Chargement />
        <App />
      </Fragment>
    );
  }
}

“App”组件是需要几秒钟渲染的组件,我正在尝试实现我的“充电”组件。我很确定这与组件生命周期有关,但到目前为止我尝试的所有内容都失败了。

我当前的堆栈是:与Redux和MaterialUi进行反应

我错过了什么?

感谢您的帮助!

Ps:你可能想检查我在主要答案评论中添加的解释和精确度,因为它们提供了进一步的背景。

2 个答案:

答案 0 :(得分:2)

不确定我是否理解正确,但我认为问题只是您的API调用比组件安装周期花费的时间更长,这是完全正常的。您可以通过重新排列放置IO的位置来解决问题。

假设您正在从AppWrapper进行API调用,请在componentDidMount中调度Redux操作,即fetchListItems()。当API调用解析时,reducer应将其内部loading值从true更改为false。然后,AppWrapper将获得chargement作为道具,其值将为false。因此,您应该检查AppWrapper的渲染方法中此值的含义。如果道具为真,则渲染Chargement组件,否则渲染ListView

此外,请始终尝试将IO与视图分离。您很可能需要在其他情况下重复使用Chargement,对吗?然后,通过渲染视图使其成为一个简单的通用组件。否则,如果您需要重用该组件,它将已经耦合到一个端点。为此,您可以使用无状态功能组件,如下所示:

const Chargement = () =>
    <Fragment>
        <div className='loadingicon'>
            <CircularProgress size={80} style={{ color: blue[500] }}/>
        </div>
        <div className='loadingBackground'/>
    </Fragment>

答案 1 :(得分:0)

我找到了一种解决我的问题的方法,不涉及像我最初计划的那样使用“收费”组件。问题围绕Material-Ui-Next librairy使用扩展面板。

我找到的解决方案如下:

我没有尝试在列表渲染时显示“加载”组件,而是通过不渲染ExpansionDetail组件来缩短列表的渲染时间,除非用户单击以展开它。

这样,在我测试过的任何设备上,列表都会在0.2秒内呈现。我将状态设置为collapsed:构造函数内的每个面板都为false。

class ListItem extends React.Component {
  constructor (props) {
    super(props);

    this.state = {
      collapsed: false
    };
    this.managePanelState = this.managePanelState.bind(this);
  }
  managePanelState () {
    if (this.state.collapsed) {
      this.setState({collapsed: false});
    } else {
      this.setState({collapsed: true});
    }
  }

然后我使用扩展面板的onChange事件在崩溃之间切换状态,而不是在每个ListItemDetail元素之间切换状态。

<ExpansionPanel onChange={() => this.managePanelState()}>

我猜有时解决方案不是你最初计划的地方。  感谢所有花时间研究我的问题的人!