如何在非父母子女反应组件之间共享数据?
问题描述:
在儿童 - 父母关系中组件之间共享数据的过程已有详细记录,并且可以直接在React文档中处理。不太明显的是如何共享不共享父子关系的组件之间的状态和任意数据。 Flux作为一种解决方案提供,过去我已经推出了自己的pub/sub系统,但在这个领域仍然存在着reactjs开发人员之间的巨大分歧。 RxJS已经作为一个解决方案提供,并且在观察者模式上提供了许多变体,但是我想知道是否有更加规范的方式来管理这个问题,特别是在组件不太紧密的大型应用程序中。如何在非父母子女反应组件之间共享数据?
答
我的解决方案通常是将回调作为道具传递给将接受用户输入的组件。该回调会执行父项中的状态更改,该更改会向下传播。例如:
UI = React.createClass({
getInitialState() {
return {
text: ""
};
}
hello(text) {
this.setState({
text: text
});
}
render() {
return (
<div>
<TextView content={this.state.text}>
<Button onclick={() => this.hello("HELLO WORLD")}>
</div>
);
}
});
// TextView and Button are left as an exercise to the reader
我喜欢这个,因为每个家长成分仍然是唯一负责其内容和子组件不侵入知道对方的任何事情;这都是回调。不可否认,大规模的反应的应用程序,但我喜欢没有一个全球事件调度管理一切,使控制流很难遵循。在本例中,UI
类将始终是完全自包含的,并且可以根据需要进行复制,而不存在名称重用的风险。
编辑:
下面是示出部件之间的更直接的关系的例子。它基本上是一样的,因为父母仍然必须促进这种关系。我更喜欢前面的例子,因为我更喜欢带有道具的小零件,而不是任何可能的状态。
UI = React.createClass({
render() {
textView = <TextView>;
return (
<div>
{textView}
<Button onclick={() => textView.setText("HELLO WORLD")}>
</div>
);
}
});
// TextView and Button are left as an exercise to the reader.
// TextView is presumed to have a setText method, which internally calls
// this.setState(...)
这是不是还不是亲子关系?如果有两个'''UI'''''“父母”组件,都意味着保持同步,都与他们自己的孩子?你能否更新你的例子? – sjt003
@ sjt003好了,在这个例子中,它是有关系的Button和TextView。父母的工作是建立和促进这种关系。在你的例子中,如果你有两个需要通信的UI组件,你可以把它们放在一个设置通信的父项下。 我已经更新了与Button和TextView有更直接的关系的示例 - Button接收直接调用TextView的setText方法的回调。但是,我通常会发现,尽可能将图上的状态提高一些,道具较低。 – Lucretiel
@ sjt003我的哲学谈到React的时候,一切可见都应该用道具和状态来管理。如果两个遥远的组件共享一些状态并需要保持同步,那么该状态应该存在于其父节点中。大多数React应用程序都有一个顶级父组件,可以在该状态下运行。你可以用一个例子来更新你的问题:一个例子中两个组件完全独立,而且它们不在单个父代之下? – Lucretiel