如何从父组件调用子组件中的事件处理程序或方法?



我正在尝试实现类似于 Material-UI 文档中的浮动操作按钮 (FAB) 的东西:

https://material-ui.com/demos/buttons/#floating-action-buttons

他们有这样的东西:

<SwipeableViews>
<TabContainer dir={theme.direction}>Item One</TabContainer>
<TabContainer dir={theme.direction}>Item Two</TabContainer>
<TabContainer dir={theme.direction}>Item Three</TabContainer>
</SwipeableViews>
{
fabs.map((fab, index) => (
<Zoom>
<Fab>{fab.icon}</Fab>
</Zoom>
));
}

我有这样的东西:

<SwipeableViews>
<TabContainer dir={theme.direction}>
<ListOfThingsComponent />
</TabContainer>
<TabContainer dir={theme.direction}>Item Two</TabContainer>
<TabContainer dir={theme.direction}>Item Three</TabContainer>
</SwipeableViews>
{
fabs.map((fab, index) => (
<Zoom>
<Fab onClick={ListOfThingsComponent.Add???}>
Add Item to List Component
</Fab>
</Zoom>
));
}

我的ListOfThingsComponent最初有一个Add按钮,效果很好。但我想像在文档中那样遵循 FAB 方法。为此,"添加"按钮将驻留在子组件之外。那么如何从父组件获取一个按钮来调用子组件的 Add 方法呢?

我不确定如何实际实现"将项目添加到列表"单击事件处理程序,因为我的列表组件位于选项卡内,而 FAB 位于整个选项卡结构之外。

据我所知,我可以:

  1. 找到一种连接父/子的方法,以通过级别传递事件处理程序(例如,如何将事件处理程序传递给 React 中的子组件)
  2. 找到一种方法来更好地组合组件/层次结构,以将责任置于正确的级别(例如,删除组件并将其放在同一个文件中,使用功能组件在范围内this

我见过人们使用ref但这感觉很黑客。我想知道应该如何在 React 中完成它。如果该示例更进一步并显示 FAB 的事件处理应驻留的位置,那就太好了。

提前感谢,一如既往,我会发布我最终做的事情

这取决于您希望点击做什么。他们是只更改给定项的状态,还是会在该层次结构之外执行更改?晶圆厂是否会出现在每个选项卡中,或者您不确定?

我认为在大多数情况下,你最好做你以前做的事情。为每个选项卡编写一个自定义组件,并让它自己处理 FAB。这可能是一种糟糕方法的唯一情况是,如果您事先知道 FAB 的回调将在 CustomComponent 层次结构中进行更改,因为在这种情况下,从长远来看,您最终可能会遇到回调混乱(尽管如此,全局状态管理无法修复)。

编辑后编辑:在 React 中,让按钮调用子组件内的函数可以说是不可能的(不诉诸 Refs 或其他完全避免 React 的机制),因为它是单向数据流。该函数必须是共同的,在本例中,在安装按钮的组件和 ListOfThings 组件中。该按钮将调用该方法,该方法将更改"Parent"组件中的状态,并且新状态通过props传递给ListOfThings组件:

export default class Parent extends Component {
state = {
list: []
};
clickHandler = () => {
// Update state however you need
this.setState({
list: [...this.state.list, 'newItem']
});
}
render() {
return (
<div>
<SwipeableViews>
<TabContainer dir={theme.direction}>
<ListOfThingsComponent list={this.state.list /* Passing the state as prop */}/>
</TabContainer>
<TabContainer dir={theme.direction}>Item Two</TabContainer>
<TabContainer dir={theme.direction}>Item Three</TabContainer>
</SwipeableViews>
{
fabs.map((fab, index) => (
<Zoom>
<Fab onClick={this.clickHandler /* Passing the click callback */}> 
Add Item to List Component
</Fab>
</Zoom>
))
}
</div>
)
}
}

如果你确实需要你的层次结构保持这种状态,你必须使用这种方法或ListOfThingsComponent可以从中读取的某种形式的全局状态管理。

相关内容

  • 没有找到相关文章

最新更新