如何更新共享同一类的所有组件的状态?

时间:2018-10-25 08:59:38

标签: reactjs setstate

此组件在我的应用中呈现了 3次

class User extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userFavorites: []
    };
    this.postFavorite = this.post.bind(this);
  }

  componentDidMount() {
    this.setState(() => ({
      userFavorites: [{ id: 1, title: "A" }, { id: 2, title: "B" }]
    }));
  }

  post() {
    const obj = { id: 3, title: "C" };
    this.setState(
      prevState => ({
        userFavorites: [...prevState.userFavorites, obj]
      }),
      () => {
        console.log("AFTER", this.state.userFavorites);
      }
    );
  }

  render() {
    return (
      <div className="container">
        <div className="button" onClick={this.post} />
      </div>
    );
  }
}

当我调用post()时,通过单击按钮,将const obj添加到userFavorites数组中,并与最后一个状态合并。 但是,它只会添加到已单击并触发方法post()的“用户”中。

有什么方法可以将状态设置为应用程序上所有3个“用户组件”,而不管哪个“用户”触发状态更新?

1 个答案:

答案 0 :(得分:1)

这三个用户组件互不了解。共享状态应在组件树中上移。

下面是一个演示该想法的微型示例。该状态存储在<Parent>中,并作为道具传递给每个<Child>,并带有要添加到该状态的回调。

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { items: [] };
    this.addItem = this.addItem.bind(this);    
  }

  render() {
    return (
      <div>
        <Child name="first" items={this.state.items} add={this.addItem} />
        <Child name="second" items={this.state.items} add={this.addItem} />
        <Child name="third" items={this.state.items} add={this.addItem} />
      </div>
    );
  }
  
  addItem(item) {
    this.setState({ items: [...this.state.items, item] });
  }
}

function Child(props) {
  return (
    <div>
      <h3>{props.name}</h3>
      {props.items.map((item, i) => (<div key={i}>{item}</div>))}
      <button onClick={() => props.add(props.name)}>add</button>
    </div>
  );
}

ReactDOM.render(<Parent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>