为什么子组件不会在组件树中更新?

时间:2019-10-07 10:17:53

标签: javascript reactjs

我尝试将状态传递给孩子,以更新对象列表。 当我添加一个条目时,它不会在子组件中呈现。 我还检查了state.contacts实际上是否已被新数组替换,但是没有用。


  constructor(props) {
    this.super(props);
  }

  removeContact(event) {
    this.setState((state) => {
      state.contacts = state.contacts.filter((contact) => contact.key !== event.target.key )
      return state;
    })
  }

  render() {
    return (
      <Fragment>
        <span>{this.props.contact.name}</span>
        <span>{this.props.contact.phone}</span>
        <span>{this.props.contact.adress}</span>
        <a href="#" onClick={this.removeContact}>X</a>
      </Fragment>
    )
  }
}

class Contacts extends Component {

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

  render() {
    console.log(this.state.contacts); // always displays empty array
    return (
      <div>
        {this.state.contacts.map((contact, index) => 
          <div>
            <Contact key={index} contact={contact} contacts={this.state.contacts}/>
          </div>
        )}
      </div>
    )
  }
}

class App extends Component {
  state = {
    time: new Date(),
    name: "",
    phone: "",
    adress: "",
    contacts: []
  }

  change = (event) => {
    let nameOfField = event.target.name;

    this.setState({[nameOfField]: event.target.value})
  }

  // click = () => { 
  //   this.setState((state) => {
  //     state.time = new Date();
  //     return state;
  //   })
  // }

  addContact = () => {
    let name = this.state.name;
    let phone = this.state.phone;
    let adress = this.state.adress;

    this.setState((state) => {
      return {contacts: [ ... state.contacts.concat([{name, adress, phone}])]}
    });

  }

  render() {
    return (
    <div className="App">
      <Timestamp time={this.state.time}/>
      <Contacts contacts={this.state.contacts}/>
      <input name="name" value={this.state.name} onChange={this.change} placeholder="Name"/>
      <input name="phone" value={this.state.phone} onChange={this.change} placeholder="Phone"/>
      <input name="adress" value={this.state.adress} onChange={this.change} placeholder="Adress"/>
      <button onClick={this.addContact}>Add contact</button>
    </div> 
    )
  }
}

ReactDOM.render(<App time={Date.now().toString()}/>, document.getElementById('root'));

2 个答案:

答案 0 :(得分:2)

如果将值传递到组件,则应将其呈现为merge。无需复制到子组件状态:

merge(x, aggregate(cbind(Amount_Avrg = Amount) ~ Id, data=x[x$Amount>0,], mean))

使用x <- read.table(header=TRUE, text="Line Id Amount 1 1 10 2 2 12 3 2 13 4 2 0 5 3 11 6 4 12 7 4 14 8 5 0 9 6 11 10 6 0") 是一个好习惯,因为它允许React确定性地渲染 (如果传递了相同的props,则返回相同的渲染结果)。

答案 1 :(得分:2)

您当前正在从Contacts的子组件Contact修改状态。您不能直接从子组件中更新父状态。

您可以做的是在removeContact组件中创建一个Contacts函数,然后将整个函数传递给Contact组件。这样,当您在子组件中调用removeContact时,它将实际上从父组件调用它,修改父组件状态,并使用新状态更新其所有子组件。