How can I structure a modal from a navbar in react

2019-08-02 09:42发布

问题:

I'm new to React, so I apologize in advance. Here's my navbar component:

import React, { Component } from 'react';
import AuthModal from './modals/AuthModal'
import { Nav, NavItem, Navbar, NavDropdown, MenuItem  } from 'react-bootstrap'

export default class MyNavbar extends Component {

  render() {

    return (
      <Navbar inverse>
        <Navbar.Header>
          <Navbar.Brand>
            <span className="logo">SITE</span>
          </Navbar.Brand>
          <Navbar.Toggle />
        </Navbar.Header>
        <Navbar.Collapse>
          <Nav className="navleft">
            <NavItem eventKey={1} href="#">Link</NavItem>
            <NavItem eventKey={2} href="#">Link</NavItem>
            <NavDropdown eventKey={3} title="Dropdown" id="basic-nav-dropdown">
              <MenuItem eventKey={3.1}>Action</MenuItem>
              <MenuItem eventKey={3.2}>Another action</MenuItem>
              <MenuItem eventKey={3.3}>Something else here</MenuItem>
              <MenuItem divider />
              <MenuItem eventKey={3.3}>Separated link</MenuItem>
            </NavDropdown>
          </Nav>
          <Nav pullRight className="navright">
            <NavItem eventKey={1} href="#"><AuthModal/></NavItem>
          </Nav>
        </Navbar.Collapse>
      </Navbar>
    );
  }
}

I need my nav to look like:

It's close:

Except, "Sign Up" and "Log In" appear to be one button currently. They need to be 2 separate buttons.

In my actual modal, I have

import React, { Component } from 'react'
import { Button, Modal, OverlayTrigger, Popover, Tooltip, Nav, NavItem, Row, Col, FormGroup, FieldGroup, Checkbox } from 'react-bootstrap'


export default class AuthModal extends Component {

  constructor() {
    super();
    this.render.bind(this);
    this.state = {showModal: false}
  }

  close() {
    this.setState({ showModal: false });
  }

  open() {
    this.setState({ showModal: true });
  }

  handleSelect(eventKey) {
    event.preventDefault();
    alert(`selected ${eventKey}`);
  }
  render () {
    const popover = (
      <Popover id="modal-popover" title="popover">
        very popover. such engagement
      </Popover>
    );
    const tooltip = (
      <Tooltip id="modal-tooltip">
        wow.
      </Tooltip>
    );
    return (
      <div>
        <span onClick={this.open.bind(this)}>Sign Up</span>
        <span onClick={this.open.bind(this)}>Log In</span>

        <Modal show={this.state.showModal} onHide={this.close.bind(this)}>
          <Modal.Body>
            <Row>
              <Col md={12}>
                <Nav bsStyle='pills' activeKey={this.eventKey} onSelect={this.handleSelect}>
                  <NavItem eventKey={1} title="Item" ><span className="login-nav-tab">Log In</span></NavItem>
                  <NavItem eventKey={1} title="Item" ><span className="login-nav-tab">Sign Up</span></NavItem>
                </Nav>
              </Col>
            </Row>
            <Row className='top-space' >
              <form>
                <FormGroup >
                  <Row>
                    <Col md={12}>
                      <input className="col-md-10 col-md-offset-1 top-space fat-input" placeholder="Email"/>
                      <input className="col-md-10 col-md-offset-1 top-space fat-input" placeholder="Password"/>
                    </Col>
                  </Row>
                  <Row className='top-space'>
                    <Col md={5} mdOffset={1}>
                      <Checkbox className="checkbox-login"> Remember Me </Checkbox>
                    </Col>
                    <Col md={6} className='forgot-password'>
                      <a href="">Forgot Password</a>
                    </Col>
                  </Row>
                  <Row className='top-space'>
                    <Col md={10} mdOffset={1}>
                      <Button bsStyle="btn btn-black btn-block">Login</Button>
                    </Col>
                  </Row>
                </FormGroup>
              </form>
            </Row>
            <hr></hr>

            <Row>
              <Col md={12} className="text-center">
               Login with blah
              </Col>
            </Row>
            <Row className="top-space">
              <Col md={6}>
                <Button bsStyle='btn btn-block btn-danger'>
                  Google
                </Button>
              </Col>
              <Col md={6}>
                <Button bsStyle='btn btn-block btn-info'>
                  Facebook
                </Button>
              </Col>
            </Row>


          </Modal.Body>
          <Modal.Footer>
            <Button onClick={this.close.bind(this)}>Close</Button>
          </Modal.Footer>
        </Modal>
      </div>
    )
  }

}

How can I have it so there's 2 separate links in the nav, and one modal. Depending on which one you click, the modal will either show the signup stuff or the sign in stuff?

回答1:

You could modify your open() instance method to accept an argument that would tell which of the modal's content to show and it's value would be stored in the component's state with setState, in say a modalType key of the state object, and in your render() method you will want to have an if statement to check against this modalType state key to display the appropriate content inside your modal's body.

export default class AuthModal extends Component {
  const MODAL_TYPE_LOGIN = 1, MODAL_TYPE_SIGNUP = 2;

  constructor() {
    super();
    this.render.bind(this);
    this.state = {
      showModal: false
    }
  }

  close() {
    this.setState({ showModal: false });
  }

  open(modalType) {
    this.setState({ 
      showModal: true,
      modalType: modalType
    });
  }

  handleSelect(eventKey) {
    event.preventDefault();
    alert(`selected ${eventKey}`);
  }

  render () {
    const popover = (
      <Popover id="modal-popover" title="popover">
        very popover. such engagement
      </Popover>
    );
    const tooltip = (
      <Tooltip id="modal-tooltip">
        wow.
      </Tooltip>
    );
    return (
      <div>
        <span onClick={this.open.bind(this, MODAL_TYPE_SIGNUP)}>Sign Up</span>
        <span onClick={this.open.bind(this, MODAL_TYPE_LOGIN)}>Log In</span>

        <Modal show={this.state.showModal} onHide={this.close.bind(this)}>
          <Modal.Body>
            <Row>
              <Col md={12}>
                <Nav bsStyle='pills' activeKey={this.eventKey} onSelect={this.handleSelect}>
                  <NavItem eventKey={1} title="Item" ><span className="login-nav-tab">Log In</span></NavItem>
                  <NavItem eventKey={1} title="Item" ><span className="login-nav-tab">Sign Up</span></NavItem>
                </Nav>
              </Col>
            </Row>
            {this.state.modalType == MODAL_TYPE_LOGIN ? (
              <Row className='top-space' >
                <form>
                  <FormGroup >
                    <Row>
                      <Col md={12}>
                        <input className="col-md-10 col-md-offset-1 top-space fat-input" placeholder="Email"/>
                        <input className="col-md-10 col-md-offset-1 top-space fat-input" placeholder="Password"/>
                      </Col>
                    </Row>
                    <Row className='top-space'>
                      <Col md={5} mdOffset={1}>
                        <Checkbox className="checkbox-login"> Remember Me </Checkbox>
                      </Col>
                      <Col md={6} className='forgot-password'>
                        <a href="">Forgot Password</a>
                      </Col>
                    </Row>
                    <Row className='top-space'>
                      <Col md={10} mdOffset={1}>
                        <Button bsStyle="btn btn-black btn-block">Login</Button>
                      </Col>
                    </Row>
                  </FormGroup>
                </form>
              </Row>
              <hr></hr>

              <Row>
                <Col md={12} className="text-center">
                 Login with blah
                </Col>
              </Row>
              <Row className="top-space">
                <Col md={6}>
                  <Button bsStyle='btn btn-block btn-danger'>
                    Google
                  </Button>
                </Col>
                <Col md={6}>
                  <Button bsStyle='btn btn-block btn-info'>
                    Facebook
                  </Button>
                </Col>
              </Row>
            ) : (
              <div>Your sign-up form goes in here</div>
            )}
          </Modal.Body>
          <Modal.Footer>
            <Button onClick={this.close.bind(this)}>Close</Button>
          </Modal.Footer>
        </Modal>
      </div>
    )
  }
}

Though, ideally you would want to use redux so that you can control which type of modal to open from anywhere in your application, even if the components aren't related. Here is an interesting read and example of a modal logic implemented using redux.