如何在不同组件之间共享状态,同时 none 个组件通过任何 parent child 关系相互连接?

How to share states between different component while none of them are connected to each other by any parent child relation?

我是 React 的新手,我觉得它很有趣。我有一个按钮,单击该按钮会将 class 中的某些状态设置为 true,并基于此按钮的标题将发生变化。 我想根据此状态更改更改其他 class 中的其他一些 React 组件。我该怎么做?

例如:

var Comp1 = React.createClass({
    getInitialState: function() {
        return { logged_in: false }
    },

    handleClick: function() {
        this.setState({logged_in: !this.state.logged_in});
    },

    render: function() {
        return <button onClick={this.handleClick}>
                   {this.state.logged_in ? "SIGN OUT" : "SIGN IN"} 
               </button>;
    }

})

这是我的第二个组件,它是单独渲染的。

var Comp2 = React.createClass({
    render: function(){
        return <div>
                   {Comp1.state.logged_in ? "You are in" : "You need a login"}
               </div>;
    }
})

这是一个组件。我想通过传递统计信息在另一个组件中使用此组件的状态(尽管我没有以复合格式使用这两个组件,因此它们本质上是独立的)或基于状态的变化我可以定义另一个状态第二个组成部分。

您需要提供一个共享对象来处理这两个对象所代表的状态。选择一个标准模型来执行此操作(例如 redux or flux)比自己提出要容易得多。学习其中一种模式对于 React 的开发至关重要。我个人推荐redux.

这是 Flux 的非常精简版。它不是一个真正的解决方案,只是提供模式的一瞥。如果你只想跳到代码,这里是 a codepen.

共享对象通常称为存储。存储保存状态,并提供订阅该状态变化的方法。改变这种状态通常是通过使用 dispatcher 调用发布一个事件来通知商店,但为了简单起见,我在商店本身

上包含了一个发布功能
let loginStore = {
  isLoggedIn: false,
  _subscribers: new Set(),
  subscribeToLogin(callback) {
    this._subscribers.add(callback);
  },
  unsubscribeToLogin(callback) {
    this._subscribers.delete(callback);
  },
  publishLogin(newState) {
    this.isLoggedIn = newState;
    this._subscribers.forEach(s => s(this.isLoggedIn));
  }
};

一旦 pub/sub 系统就位,组件将需要订阅它。登录按钮改变了这个状态,所以它也会发布。

class LoginButton extends React.Component {
  constructor(...args) {
    super(...args);
    this.state = {isLoggedIn: loginStore.isLoggedIn};
  }
  update = (isLoggedIn) => {
    this.setState({isLoggedIn});
  }
  componentDidMount() {
    loginStore.subscribeToLogin(this.update);
  }
  componentDidUnmount(){
    loginStore.unsubscribeToLogin(this.update);
  }
  handleClick = () => {
    loginStore.publishLogin(!this.state.isLoggedIn);
  }
  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isLoggedIn ? "SIGN OUT" : "SIGN IN"} 
      </button>
    );
  }
}

class LoginHeader extends React.Component {
  constructor(...args) {
    super(...args);
    this.state = {isLoggedIn: loginStore.isLoggedIn};
  }
  update = (isLoggedIn) => {
    this.setState({isLoggedIn});
  }
  componentDidMount() {
    loginStore.subscribeToLogin(this.update);
  }
  componentDidUnmount(){
    loginStore.unsubscribeToLogin(this.update);
  }
  render() {
    return (
      <div>{this.state.isLoggedIn ? "You are in" : "You need a login"}</div>
    );
  }
}

您会注意到第二个组件不是指第一个组件的状态,而是指商店的状态。正如您所提到的,由于它们彼此之间没有引用,并且没有共同的父级,因此它们 不能 loggedIn 状态下直接相互依赖。