反应-子组件在接收新道具时不会更新

时间:2018-10-04 20:24:19

标签: javascript reactjs

我必须在react中创建一个点页面指示器组件。我首先创建了一个点组件,然后创建了实际的指示器组件。但是我有一个问题。

指示符组件的状态取决于其接收的道具,并且还必须设置沿道具向下传递的各个点的状态。为了在新道具进入时更新状态,我使用了data Expr

componentWillReceiveProps

这是点组件

class PageIndicator extends React.Component{

constructor(props){
    super(props);
    let pills = [];
    for(var i = 0;i<props.size;i++) //Create an array of all the pills required to create the page indicator
        if(i == this.props.activeIndice) //Check which of the pills is the active one - active is true
            pills.push(<PageIndicatorPill key={i} active={true}/>);
        else
            pills.push(<PageIndicatorPill key={i} active={false}/>);

    this.state = {pills:pills};
}

componentWillReceiveProps(nextProps){
    let pills = [];
    for (var i = 0; i < nextProps.size; i++) //Update the indicator
        if (i == nextProps.activeIndice) //Check which of the pills is the active one - active is true
            pills.push(<PageIndicatorPill key={i} active={true} />);
        else
            pills.push(<PageIndicatorPill key={i} active={false} />);

    this.setState({ pills: pills });
}

如果我继续进行操作,并在控制台上记录状态,它们会更新,但问题是该组件似乎并没有相应地重新渲染,因此我不知道为什么。你能帮我吗?

1 个答案:

答案 0 :(得分:1)

您的状态正在更新,但是您只能在PageIndicatorPill组件的构造函数中设置样式。 this.style需要在componentWillReceiveProps方法内进行更新。

但是。.您提供的示例可以对此进行很多简化。无需将活动道具的状态镜像为image。您可以执行以下操作:

class PageIndicatorPill extends React.Component{

  getStyle() {
    const { active } = this.props;
    return {
        backgroundImage: `url(${active ? onState : offState})`,
        marginRight: '10px', 
        height: '32px', 
        width: '32px',
        display: 'inline-block'
    };
  }

  render() {
    return (
      <div style={this.getStyle()} />
    );
  }
}

您没有发布渲染函数,因此该示例只是直接使用props来获取样式的简单演示,但希望以上内容有意义。

您的其他组件也可以简化,不需要状态...

class PageIndicator extends React.Component{

  getPills() {
    const { size, activeIndice } = this.props;
    let pills = [];
    for (let i = 0; i < size; i++) {
      pills.push(
        <PageIndicatorPill key={i} active={i === activeIndice} />
      );
    }
    return pills;
  }

  render() {
    return (
      <div>
        {this.getPills()}
      </div>
    );
  }
}