Один из способов решить эту проблему - иметь флаги (как в 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
в качестве свойств, мы можем вызывать их непосредственно в InfoButton
и 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>
)
}
}