问题 Reactjs如何从不同的组件更改组件的状态


我有一个react组件,我们将其称为组件1

define([..., /path/component_2.jsx], function(..., Component2) {
   var Component1 = React.createClass({
      getInitialState: function() {
         return {.......};
      },

      componentDidMount: function() {
          .......
          dates = ....;
          Component2.setState({dates: dates});
      }
       render: function() { return (<div ...></div>) }
   });
}

如您所见,我在此组件中调用Component2.setState。但我得到一个错误,如setState不是一个函数。我尝试在组件2中定义一个自定义函数而不是setState函数,并从组件1调用此函数,但我得到相同的错误,'不是函数'。

和组件2:

define([..., ], function(...) {
   var Component2 = React.createClass({
      getInitialState: function() {
         return {.......};
      },

      render: function() { return (<div ...></div>) }
   });
}

所以我想在reactjs中我们只调用一个组件来渲染某些东西(React DOM元素)?并且不能改变组件状态?

如果是这样,我如何从不是第一个孩子或父母的不同组件中更改组件的状态?


4508
2017-11-19 10:08


起源



答案:


组件不公开暴露其状态。同样重要的是要记住,国家的范围是  组件,而不是它们的定义。

要在组件之间进行通信,您可以推送自己的事件订阅服务。

var events = new EventEmitter();

// inside Component1
events.emit('change-state', newState);

// inside Component2
events.on('change-state', function(state) {
  this.setState(state);
});

但是,这很快就会变得难以管理。

一个更明智的解决方案是使用 助焊剂。它允许您显式管理整个应用程序的状态,并在组件内订阅状态的不同位的更改。值得尝试包围它。

想要进行通信的组件应该分派一个动作,这个动作将负责更改商店中的某些内容,您的其他组件应该订阅该商店并可以根据更改更新其状态。


10
2017-11-19 10:17





您可以在两个组件之间使用共享状态。 你可以像这样构建一个“mixin”

app.mixins.DateMixin = {
   getInitialState: function () 
      return {
          dates: []
         }
      }
};

然后在你的组件中,你可以使用mixins数组包含这个mixins

define([..., /path/component_2.jsx], function(..., Component2) {
   var Component1 = React.createClass({

      mixins: [app.mixins.DateMixin],

      getInitialState: function() {
         return {.......};
      },

      componentDidMount: function() {
          .......
          dates = ....;
          this.setState({dates: dates});
      }
       render: function() { return (<div ...></div>) }
   });
}

define([..., ], function(...) {

   mixins: [app.mixins.DateMixin],

   var Component2 = React.createClass({
      getInitialState: function() {
         return {.......};
      },

      render: function() { return (<div ...></div>) }
   });
}

现在,您的组件共享“日期”状态,您可以在两个组件中更改/检查它。 注意:您也可以通过写入mixin组件以相同的方式共享方法。

编辑:我建议你访问这个网站 http://simblestudios.com/blog/development/react-mixins-by-example.html


1
2017-11-19 10:29



反应计划 最终弃用mixins,所以今后最好尝试找到不依赖它们的解决方案。 - Dan Prince
@DanPrince真的吗?嗯..刚刚阅读了关于rakwaht发布的mixins的好文档 - Abhi
它不会在下一个版本中发生,但React团队正在努力寻找更好的解决方案。有一个讨论 这里。 - Dan Prince
@DanPrince在这里我发布了回购所有者的回答。 “我们还没有准备好弃用mixin,因为我们没有对所有用例进行良好的替换。当我们这样做时,我们可能会转向弃用mixins和React.createClass,但这至少需要几个月的时间。”但是我认为你是对的,找到另一种方法更好,但是现在这是解决这类问题的唯一模式。 - rakwaht
请记住,这是发布于6月9日,也就是4个月前。根据React v0.14的变化情况,如果在接下来的几个版本中弃用它们,我不会感到惊讶。 - Dan Prince


答案:


组件不公开暴露其状态。同样重要的是要记住,国家的范围是  组件,而不是它们的定义。

要在组件之间进行通信,您可以推送自己的事件订阅服务。

var events = new EventEmitter();

// inside Component1
events.emit('change-state', newState);

// inside Component2
events.on('change-state', function(state) {
  this.setState(state);
});

但是,这很快就会变得难以管理。

一个更明智的解决方案是使用 助焊剂。它允许您显式管理整个应用程序的状态,并在组件内订阅状态的不同位的更改。值得尝试包围它。

想要进行通信的组件应该分派一个动作,这个动作将负责更改商店中的某些内容,您的其他组件应该订阅该商店并可以根据更改更新其状态。


10
2017-11-19 10:17





您可以在两个组件之间使用共享状态。 你可以像这样构建一个“mixin”

app.mixins.DateMixin = {
   getInitialState: function () 
      return {
          dates: []
         }
      }
};

然后在你的组件中,你可以使用mixins数组包含这个mixins

define([..., /path/component_2.jsx], function(..., Component2) {
   var Component1 = React.createClass({

      mixins: [app.mixins.DateMixin],

      getInitialState: function() {
         return {.......};
      },

      componentDidMount: function() {
          .......
          dates = ....;
          this.setState({dates: dates});
      }
       render: function() { return (<div ...></div>) }
   });
}

define([..., ], function(...) {

   mixins: [app.mixins.DateMixin],

   var Component2 = React.createClass({
      getInitialState: function() {
         return {.......};
      },

      render: function() { return (<div ...></div>) }
   });
}

现在,您的组件共享“日期”状态,您可以在两个组件中更改/检查它。 注意:您也可以通过写入mixin组件以相同的方式共享方法。

编辑:我建议你访问这个网站 http://simblestudios.com/blog/development/react-mixins-by-example.html


1
2017-11-19 10:29



反应计划 最终弃用mixins,所以今后最好尝试找到不依赖它们的解决方案。 - Dan Prince
@DanPrince真的吗?嗯..刚刚阅读了关于rakwaht发布的mixins的好文档 - Abhi
它不会在下一个版本中发生,但React团队正在努力寻找更好的解决方案。有一个讨论 这里。 - Dan Prince
@DanPrince在这里我发布了回购所有者的回答。 “我们还没有准备好弃用mixin,因为我们没有对所有用例进行良好的替换。当我们这样做时,我们可能会转向弃用mixins和React.createClass,但这至少需要几个月的时间。”但是我认为你是对的,找到另一种方法更好,但是现在这是解决这类问题的唯一模式。 - rakwaht
请记住,这是发布于6月9日,也就是4个月前。根据React v0.14的变化情况,如果在接下来的几个版本中弃用它们,我不会感到惊讶。 - Dan Prince