React:如何在父更改时通过数组更新生成子组件?

时间:2018-01-18 15:58:32

标签: javascript arrays reactjs webpack

我有它所以添加多个组件并在使用状态数组单击“打开”按钮时呈现。我想拥有它,以便当我单击“更改”按钮时,它将更改列表中这些组件的数据的状态,它应该更新,但事实并非如此。

当我使用状态数组渲染多个组件时,它不会更新数组中子组件中的props。但是当我只是直接在渲染函数中渲染重复的组件时,它可以工作,但这不是我想要的功能。我需要能够在点击时添加组件,并且还可以使用不同的按钮单击更改这些子组件的值。我怎么能这样做?

Main
constructor(props) {
    super(props)
    this.state = {renderWindow: false, windowArray: [], currentWindowData: "initial"}
    this.change= this.change.bind(this)
    this.open= this.open.bind(this)
}

open() {
   const newWindow = <Window key={shortid.generate()} body={this.state.currentWindowData}/>;
    this.setState({
        renderWindow: true, 
        windowArray: [newWindow, ...this.state.windowArray]
     })
}

change(val) {
    this.setState({currentWindowData: val});
}

render() {
    return (
      <div>
        <button onClick = {() => this.open()}/>
        <button onClick = {() => this.change("ABC")}/>
        <button onClick = {() => this.change("XYZ")}/>
        {this.state.renderWindow ? this.state.windowArray : null}
      </div>
    )
}

在这个窗口组件中,我只渲染this.props.body,甚至设置componentWillReceiveProps生命周期钩子只是为了安全并呈现该数据,如果我可以接收它但它仍然不会更新。

Window
constructor(props) {
    super(props);
}

componentWillReceiveProps(nextProps) {
    this.setState({bodyData: nextProps.body});
}

render() {
    return (
        <div>
            {this.props.body}   
            {this.state.bodyData}
        </div> 
    );
}

但是当我在主组件中更改渲染功能并在那里渲染一个重复的Window组件列表而不是从状态数组中时,它可以工作。是什么给了什么?

render() {
    return (
      <div>
        <button onClick = {() => this.open()}/>
        <button onClick = {() => this.change("ABC")}/>
        <button onClick = {() => this.change("XYZ")}/>
        {<Window key={shortid.generate()} body={this.state.currentWindowData}/>}
        {<Window key={shortid.generate()} body={this.state.currentWindowData}/>}
        {<Window key={shortid.generate()} body={this.state.currentWindowData}/>}

      </div>
    )
}

1 个答案:

答案 0 :(得分:1)

您正在Window方法中创建open个实例。您为实例提供了一些属性,并将实例保存在您的状态中。当您重新渲染时,请从您所在的州获取实例并显示它们。

请注意,您在open方法中设置了一次属性。在以后的时间点道具更新道具。如果要在调用render方法时更新属性,则必须clone your windows with new props或在所在州中存储所需的属性,然后在render方法中生成实例(正如你在第二个例子中所做的那样)。

open() {
  const id = shortid.generate();
  this.setState({
    // ...,
    windowIDs: [id, ...this.state.windowIDs]
  });
}

render() {
  const windows = this.state.windowIDs.map(
    id => <Window key={id} body={this.state.currentWindowData} />
  );
  return (
    <div>
      // ...
      { windows }
    </div>
  );
}