【问题标题】:[React]: rendering through this.props.children always unmounts and mounts all children instead of just re-rendering[React]:通过 this.props.children 渲染总是卸载和安装所有子节点,而不是重新渲染
【发布时间】:2016-09-16 03:32:07
【问题描述】:

我在 react 中创建了一个具有扩展折叠功能的手风琴。 渲染:

<div>
    <div>
        <label className="label">
            { this.props.label }
        </label>
    </div>
    <div style={{ display: !!this.state.expanded ? "block" : "none" }}>
{ this.props.children } </div>
</div>

我这样称呼它:

<Accordion>
    <MyComponent1/>
    <MyComponent2/>
    <MyComponent3/>
</Accordion>

但每次手风琴展开/折叠时,子组件都会被卸载。因此,他们会丢失自己的任何数据/状态,我必须保留所有内容 发生展开折叠时也不会重新渲染。

当发生折叠扩展时,子组件不应该只是重新渲染而不是卸载和重新安装。有没有办法达到同样的效果。 我不想保留每个子组件的状态

@Drew Schuster:完整代码-

导出类 Accordion 扩展 React.Component {

constructor(props) {
    super(props);
    this.state = {
        expanded: false
    }
}

public render(): JSX.Element {
    let className = My_String_Util.format("chevron-", this.state.expanded ? "down" : "right");
    return (
        <div>
            <div onClick={ this._toggle }>
                <label className={ className }  />
                <label className="label"> { this.props.label } </label>
            </div>
            <If condition={ this.state.expanded }>
                <div style={{
                    display: !!this.state.expanded ? "block" : "none"
                }}>{ this.props.children }</div>
            </If>
        </div>
    );
}

private _toggle = (): void => {
    this.setState({
        expanded: !this.state.expanded
    });
}

}

父组件:

render(): JSX.Element {
    <Accordion label="Sample Accordion2" expanded={true} >
        <MyChildComponent
                        sampleProp={"aa"}
                        stringParentProp={"initial string"}/>
                    <label>"Hello World3"</label>

                    </Accordion>
}

我的孩子组件:

constructor(props) {
this.state = {
stateString = this.props.stringParentProp
}
}
render(): JSX.Element {
<div onClick={this._changeLabel}>
    <label>this.state.stateString</label>
</div>
}

private _changeLabel() {
this.setState = {
stateString = this.state.stateString + "x";
}
}

这应该在我们每次点击子组件时添加'x'到它的标签。哪个有效。但是当我们折叠然后再次展开时,标签会重置为“初始字符串”

【问题讨论】:

  • 你能发布更多代码吗?到目前为止,您提交的代码应该可以按预期工作,查看整个手风琴组件以及调用它的位置可能会更有帮助。
  • @DrewSchuster 添加了有问题的代码

标签: reactjs react-jsx


【解决方案1】:

包含的代码有一些错误导致无法编译。我删除了一些不需要重现此错误的代码,现在在codepen 有一个可行的解决方案。代码也包括在下面,我使用 React.createClass 而不是扩展 React.Component 但你当然不必这样做。:

const Accordion = React.createClass({
  getInitialState: function () {
    return { expanded: false }
  },

  _toggle: function () {
      this.setState({
          expanded: !this.state.expanded
      });
  },
  render: function () {
    return (
        <div>
            <div onClick={ this._toggle }>
                <label className={ className }  />
                <label className="label"> { this.props.label } </label>
            </div>
            <div style={{
                display: !!this.state.expanded ? "block" : "none"
              }}>{ this.props.children }</div>
        </div>
    );
  }
});

const MyChildComponent = React.createClass({
  getInitialState: function () {
    return { stateString: this.props.stringParentProp}
  },
  _changeLabel: function () {
    this.setState(
      {
      stateString: this.state.stateString + "x"
    })
  },
  render: function () {
    return (
      <div onClick={this._changeLabel}>
        <label>{this.state.stateString}</label>
      </div>
    )
  }
})

const Parent = () => {
    return (
      <Accordion label="Sample Accordion2" expanded={true} >
          <MyChildComponent
            sampleProp="aa"
            stringParentProp="initial string"/>
          <label>"Hello World3"</label>
      </Accordion>
    )
}


ReactDOM.render(<Parent/>, document.getElementById('container'))

【讨论】:

  • 它总是为我卸载组件。我想要一些刚刚重新渲染组件的东西
  • 在我上面提供的代码中,组件没有被卸载
  • 在你的代码 sn-p 中有很多不能正常工作的地方,比如 MyChildComponent &lt;label&gt;this.state.stateString&lt;/label&gt; 应该是 &lt;label&gt;{this.state.stateString}&lt;/label&gt; 否则你的标签只会说“this.state.stateString” .可能给您带来问题的是您在 MyChildComponent 中使用了this.setState。不应该是this.setState = ...,应该是this.setState({stateString: this.state.stateString + "x"})
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-07
  • 1970-01-01
  • 2019-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多