JVilla JVilla - 2 months ago 25
React JSX Question

Open modal with ReactJS (es6) and siblings components

I have my app component with a Navbar component, and a ModalLogin component.

App component:

class App extends React.Component {
render() {
return (
<div>
<Navbar history={this.props.history} />
{this.props.children}
<ModalLogin />
</div>
);
}
}


Navbar component

class Navbar extends React.Component {
constructor(props) {
super(props);
this.state = NavbarStore.getState();
this.onChange = this.onChange.bind(this);
}

componentDidMount() {
NavbarStore.listen(this.onChange);
}

onChange(state) {
this.setState(state);
}

render() {
return (
<nav className='navbar navbar-default navbar-static-top'>
<ul className='nav navbar-nav'>
<li><a href="#">Login</a></li>
</ul>
</nav>
)
}


And the ModalLogin uses react-bootstrap:

render() {
return (
<div>
<Modal show={this.state.showModal} onHide={ModalLoginActions.close}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>
</Modal.Body>
</Modal>
)
}


But as you can see, Navbar and Modal are siblings in my app. Is this the correct way?

Answer

write an onClick handler that triggers an event in the parent.

render() {
   return (
     <nav className='navbar navbar-default navbar-static-top'>
        <ul className='nav navbar-nav'>
           <li><a href="#" onClick={this.props.onLogin}>Login</a></li>
        </ul>
     </nav>
  )

Add a handler to the App component which sets showModal state to true.

<Navbar 
  history={this.props.history} 
  onLogin={() => this.setState({showModal: true})}
/>

Pass the showModal to the ModalLogin component.

<ModalLogin showModal={this.state.showModal} />

Within the ModalLogin, use the props to show the Modal.

Modal show={this.props.showModal} onHide={ModalLoginActions.close}>