我有一个主要组件App
,根据路线包含一些孩子(我使用react-router
)等等:
class App extends Component {
otherClick = () => { /* run every children's `handleButton2` function */ }
<div className="App">
<Button handleMenuClick={this.toggleSideBar}>Button 1</Button>
<Button handleOtherClick={this.otherClick}>Button 2</Button>
<SideBar ref="sideBar" title="Toto"/>
{this.props.children}
</div>
}
因此,根据路线,App
将包含一些其他容器,例如:
class ContainerABC extends React.Component {
constructor(props) {
super(props);
}
handleButton2 = () => {
let sc = this.refs.subCont;
sc.setState({visible : !sc.visible});
// Change the color of Button 2 ???
};
render() {
return (
<div>
<SubContainer ref="subCont"/>
</div>
);
}
};
Button 2的作用取决于当前的Container。在上面的示例中,当我有一个ContainerABC
作为孩子时,我希望Button 2
切换SubContainer
ContainerABC
。
如何根据组件的子项告诉Button 2执行适当的操作?
和/或当Button 2
触发对SubCont
的操作时,如何修改Button 2
(或任何触发器)来自SubCont
?
也许使用Redux?我不知道它有什么用处
答案 0 :(得分:4)
Redux 可能只是因为它可以触发一个操作,反过来它会修改全局状态树(例如通过reducer存储redux)。如果这是您需要实现的唯一目的,那么我建议不要增加复杂性(尽管我喜欢Redux)。
我假设您希望{this.props.children}
的随机孩子在点击按钮2时触发一个随机动作?
让我们观察一下这种常用的React模式: 属性向下流动。动作(阅读:回调)向上。
也就是说,您可能需要遍历{this.props.children}
并检查是否存在符合API要求的特殊回调道具。
React.Children.forEach(this.props.children, (child) => {
if (typeof child.props.toggleButton2State !== "function") {
throw('Woah, cowboy, you need that toggleButton2State function);
}
}
然后你的按钮可以以相同的方式循环访问子节点并执行该函数(如果存在)。
handleButton2Click() {
React.Children.forEach(this.props.children, (child) => {
if (typeof child.props.toggleButton2State === "function") {
child.props.toggleButton2State.call(child, !oldState, this);
}
}
}
所以你只是在孩子的范围内调用了孩子的回调函数,其中布尔状态被切换,你也将引用传递给父组件(this)。
我强烈建议你永远不要操纵孩子的父容器。你永远不知道你的等级可能会如何变化。
显然,这是一个非常粗略的例子,但它应该让你去。让我知道事情的后续。
答案 1 :(得分:0)
如果按钮的行为取决于正在呈现的容器,那么听起来像容器应该呈现按钮。您可以连接一些道具(甚至可以使用cloneElement将它们放在孩子身上),这样您就可以通过回调来改变按钮的行为,但这听起来像是一个难以维持的噩梦。
您可以将这些按钮放在一个单独的组件中(使用prop来确定它们的作用)并将其呈现在容器中。这对我来说听起来更简单。