reactjs - 在 React 中打开另一个对话框时如何自动关闭一个对话框
问题描述
我正在制作一个带有导航栏的反应应用程序,如上图所示。导航栏是一个名为“TopButtonsBar”的组件。在此 TopButtonsBar 组件内呈现的是上面每个按钮图片的组件。这些组件从左到右依次是 InfoButton、NotificationsButton 等。每个按钮组件都管理自己的状态,该状态指示是否应显示给定按钮的对话框。以下是按钮组件的外观,以 InfoButton 组件为例。
export default class InfoButton extends React.Component{
constructor(props){
super(props);
this.state = {
isDialogueOpen:false,
isHoveringOver:false
};
this.handleOpenDialogue = this.handleOpenDialogue.bind(this);
this.handleHoverOver = this.handleHoverOver.bind(this);
}
**handleOpenDialogue = (e) => {
e.preventDefault();
this.setState((prevState) => ({
isDialogueOpen:!prevState.isDialogueOpen
}));
}**
handleHoverOver = (e) => {
e.preventDefault();
if(!this.state.isDialogueOpen){
this.setState((prevState) => ({
isHoveringOver:!prevState.isHoveringOver
}));
}
}
render(){
return(
<div className="navbar-button">
<img
onMouseOver={this.handleHoverOver}
onMouseLeave={this.handleHoverOver}
onClick={this.handleOpenDialogue}
src={this.state.isHoveringOver?infoButtonHovered:infoButtonNotHovered} alt="Info"
/>
{this.state.isHoveringOver && !this.state.isDialogueOpen && <InfoRollover />}
**{this.state.isDialogueOpen && <InfoDialogue />}**
</div>
)
}
}
重要的位是 *用星号 * 括起来的。此逻辑在按钮单独级别上运行良好。我想要做的是:如果,如上图,选择了消息通知按钮,如果我点击信息按钮,我希望消息通知按钮关闭,同时信息按钮打开。但是,我在概念化我应该如何重新配置状态方面一直没有成功。如果任何按钮已关闭,TopButtonsBar 组件是否应该保存有关状态的信息?如果是这样,我将如何重新处理按钮的打开方式(以及单个按钮组件是否应该控制该状态)。另外,我没有使用任何状态管理器,例如 Redux、Hooks 等。谢谢!
解决方案
解决此问题的一种方法是在父组件的状态 ( ) 中拥有isDialogueOpen
所有子组件 (InfoButton
等) 的标志 (如)。NotificationButton
TopButtonsBar
TopButtonsBar.js
我将首先添加一些标识每个对话框的常量。之后,我们可以声明一个状态,该状态将指向打开的对话框。
只需遵循以下代码中的注释即可更好地理解。
// adding some constants here
const INFO_BUTTON = 'INFO_BUTTON';
const NOTIFICATION_BUTTON = 'NOTIFICATION_BUTTON';
export default class TopButtonsBar extends React.Component {
constructor(props) {
super(props);
this.state = {
...
// adding this state to point out which dialogue is open
selectedDialogue: null
}
}
handleOpenDialogue = (e, selectedDialogue) => {
e.preventDefault();
if (selectedDialogue === this.state.selectedDialogue) {
// close dialogue if already open
this.setState({selectedDialogue: null});
} else {
// else open this dialogue
this.setState({selectedDialogue});
}
}
....
render() {
return (
....
<InfoButton
isDialogueOpen={this.state.selectedDialogue === INFO_BUTTON}
handleOpenDialogue={(e) => handleOpenDialogue(e, INFO_BUTTON)}
...
/>
<NotificationButton
isDialogueOpen={this.state.selectedDialogue === NOTIFICATION_BUTTON}
handleOpenDialogue={(e) => handleOpenDialogue(e, NOTIFICATION_BUTTON)}
...
/>
)
}
}
InfoButton.js
现在我们将组件的状态及其处理函数TopButtonsBar
作为 props 传递,我们可以直接在InfoButton
and中调用它们NotificationButton
,而无需任何相关的本地状态。
export default class InfoButton extends React.Component{
constructor(props){
super(props);
this.state = {
// removing the state from here
isHoveringOver:false
};
this.handleHoverOver = this.handleHoverOver.bind(this);
}
// removing the handleOpenDialogue function here
...
render(){
return(
<div className="navbar-button">
<img
onMouseOver={this.handleHoverOver}
onMouseLeave={this.handleHoverOver}
// calling handleOpenDialogue from props
onClick={this.props.handleOpenDialogue}
...
/>
// using isDialogueOpen from props now
{this.state.isHoveringOver && !this.props.isDialogueOpen && <InfoRollover />}
{this.props.isDialogueOpen && <InfoDialogue />}
</div>
)
}
}
推荐阅读
- django - 会话到期 Django
- python - 烧瓶登录 User.get(userid) 丢失
- python-3.x - 如何从python3中的另一个包中导入模块?
- android - addTextChangedListener 第二次无法正常工作-Android Kotlin Viewmodel
- android - 您所在的国家/地区不支持 Google Play 购买
- time-series - 使用 LSTM-Seq2seq 模型训练多个数据集
- npm - UnhandledPromiseRejectionWarning:错误:“版本”是必需的参数
- python - 如何在不使用替换函数或任何内置函数的情况下从 python 中的主字符串替换子字符串?
- python - 如何为 html 模板提供参数?
- python - 如何在 tkinter.ttk.Entry 中设置文本框等待输入模式