简体   繁体   中英

ReactJS- render modal component on onclick event

I am trying to add ReactStrap Modal to my NavBar but couldn't find solution to it. I created a handler function which will be called upon click event but I am not able to call my login component on this handler function. I also bind the handler to the current DOM. What i have done is simply called Login component which is not working. Please explain how can I call component form this parent component

Code: login.js

import React from 'react';
import {
    Button,
    Form,
    FormGroup,
  //  FormText,
    Label,
    Input,
    Modal,
    ModalHeader,
    ModalBody,
    ModalFooter
} from 'reactstrap';

class Login extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            modal: false
        };
        this.toggle = this.toggle.bind(this);
    }

    toggle() {
        this.setState({
            modal: !this.state.modal
        });
    }

    render() {
        return (
            <div>
              <Button color="danger" onClick={this.toggle}>{this.props.buttonLabel}</Button>
              <Modal isOpen={this.state.modal} toggle={this.toggle} className={this.props.className}>
                <ModalHeader toggle={this.toggle}>Login</ModalHeader>
                <ModalBody>
                      <Form>
                          <FormGroup>
                              <Label for="Email">Email</Label>
                              <Input type="email" name="email" id="email" placeholder=""/>
                          </FormGroup>
                          <FormGroup>
                              <Label for="password">Password</Label>
                              <Input type="password" name="password" id="password" placeholder=""/>
                          </FormGroup>
                      </Form>
                </ModalBody>
                <ModalFooter>
                  <Button color="primary" onClick={this.toggle}>Submit</Button>{' '}
                  <Button color="secondary" onClick={this.toggle}>Cancel</Button>
                </ModalFooter>
              </Modal>
            </div>
          );
    }
}

export default Login;

NavBar.js:

import React from 'react';
import Login from './login/login';
import {
    Navbar,
    NavbarBrand,
    NavbarToggler,
    Nav,
    NavItem,
    NavLink,
    Collapse,
    UncontrolledDropdown,
    DropdownMenu,
    DropdownItem,
    DropdownToggle
} from 'reactstrap';

class NavbarComponent extends React.Component {
    constructor(props) {
        super(props);

        this.toggle = this.toggle.bind(this);
        this.state = {
            isOpen: false
        };
        this.handleClick = this.handleClick.bind(this);
**this.setState={
          isloggedOn: true
        }**

    }

    stickyNavbar() {
        var Navbar = document.getElementById("Navbar");
        console.log(Navbar);
        var sticky = Navbar.offsetTop;
        if (window.pageYOffset >= sticky) {
          Navbar.classList.add("sticky")
        } else {
          Navbar.classList.remove("sticky");
        }
      }

    toggle() {
        this.setState({
            isOpen: !this.state.isOpen
        });
    }

    handleClick() {
      **if(this.isloggedOn) {
    return <Login/>;
  }**
    }

    render() {
        return (
            <div>
                <Navbar color="dark" light expand="md">
          <NavbarBrand href="/">found-Missing</NavbarBrand>
          <NavbarToggler onClick={this.toggle} />
                <DropdownMenu right>
                  <DropdownItem onClick= {this.handleClick}>
                    Login
                  </DropdownItem>
                  <DropdownItem href="https://github.com/reactstrap/reactstrap">
                    Signup
                  </DropdownItem>
                  <DropdownItem divider />
                  <DropdownItem>
                    Reset
                  </DropdownItem>
                </DropdownMenu>
        </Navbar>
            </div>
        )
    }
} 

export default NavbarComponent;

如果要从NavBar内触发模态,只需向<NavBar />添加一个prop以在login.js状态内切换modal

There are a few things wrong with your code.

  • The isLoggedOn in your NavBarComponent should reside in the state. You have put it in setState .
  • Your handleClick method is returning a react component. This is not right. It should just take care of toggling the state.
  • As others have said, you need to use conditional rendering . With all these changes, your NavBarComponent should look like this:

     import React from 'react'; import Login from './login/login'; import { Navbar, NavbarBrand, NavbarToggler, Nav, NavItem, NavLink, Collapse, UncontrolledDropdown, DropdownMenu, DropdownItem, DropdownToggle } from 'reactstrap'; class NavbarComponent extends React.Component { constructor(props) { super(props); this.toggle = this.toggle.bind(this); this.state = { isOpen: false, isLoggedOn: false }; this.handleClick = this.handleClick.bind(this); } stickyNavbar() { var Navbar = document.getElementById("Navbar"); console.log(Navbar); var sticky = Navbar.offsetTop; if (window.pageYOffset >= sticky) { Navbar.classList.add("sticky") } else { Navbar.classList.remove("sticky"); } } toggle() { this.setState({ isOpen: !this.state.isOpen }); } handleClick() { this.setState({ isLoggedOn: true }) } render() { return ( <div> <Navbar color="dark" light expand="md"> <NavbarBrand href="/">found-Missing</NavbarBrand> <NavbarToggler onClick={this.toggle} /> {this.state.isLoggedOn ? <div>User successfully logged in!!</div> : ( <DropdownMenu right> <DropdownItem onClick= {this.handleClick}> Login </DropdownItem> <DropdownItem href="https://github.com/reactstrap/reactstrap"> Signup </DropdownItem> <DropdownItem divider /> <DropdownItem> Reset </DropdownItem> </DropdownMenu> )} </Navbar> </div> ) } } export default NavbarComponent; 

Alright I have solved the issue.

I created a state in my component and passed that state to my component along with the method(which changes the current state on onclick event) from which component can access it from parent component.

Once the component renders modal, it will call loginmodals method of parent component and change the current state and return the current state to parent component.

Now current state is false, again Parent component will call login component with new state ie false on which Modal will look at the state which is false, so it will close the Modal.

Login.js:

import React from 'react';
import {
    Button,
    Form,
    FormGroup,
    Label,
    Input,
    Modal,
    ModalHeader,
    ModalBody,
    ModalFooter
} from 'reactstrap';

class Login extends React.Component {
    constructor(props) {
        console.log(props);
        super(props);
    }

    render() {
        return (
            <div onClick={this.props.loginmodals}>
              {/* <Button color="danger" onClick={this.toggle}>{this.props.buttonLabel}</Button> */}
              <Modal isOpen={this.props.loginmodal} toggle={this.props.loginmodals} className={this.props.className}>
                <ModalHeader toggle={this.props.loginmodals}>Login</ModalHeader>
                <ModalBody>
                      <Form>
                          <FormGroup>
                              <Label for="Email">Email</Label>
                              <Input type="email" name="email" id="email" placeholder=""/>
                          </FormGroup>
                          <FormGroup>
                              <Label for="password">Password</Label>
                              <Input type="password" name="password" id="password" placeholder=""/>
                          </FormGroup>
                      </Form>
                </ModalBody>
                <ModalFooter>
                  <Button color="primary" onClick={this.toggle}>Submit</Button>{' '}
                  <Button color="secondary" onClick={this.toggle}>Cancel</Button>
                </ModalFooter>
              </Modal>
            </div>
          );
    }
}    
export default Login;

Navbar.js:

import React from 'react';
import Login from './login/login';
import {
    Navbar,
    NavbarBrand,
    NavbarToggler,
    Nav,
    NavItem,
    NavLink,
    Collapse,
    UncontrolledDropdown,
    DropdownMenu,
    DropdownItem,
    DropdownToggle
} from 'reactstrap';

class NavbarComponent extends React.Component {
    constructor(props) {
        super(props);

        this.toggle = this.toggle.bind(this);
        this.state = {
            isOpen: false,
            loginmodal: false,
            signupmodal: false
        };
        this.loginmodals = this.loginmodals.bind(this);
    }

    toggle() {
        this.setState({
            isOpen: !this.state.isOpen
        });
    }

    loginmodals(state) {
      this.setState({
        loginmodal: !this.state.loginmodal,
      });
    }

    render() {
        return (
            <div>
                <Navbar color="" light expand="md">
                <NavbarBrand href="/">found-Missing</NavbarBrand>
                <NavbarToggler onClick={this.toggle} />
                <Collapse isOpen={this.state.isOpen} navbar>
                  <Nav className="ml-auto" navbar>
                    <NavItem>
                      <NavLink href="/components/">About us</NavLink>
                    </NavItem>
                    <NavItem>
                      <NavLink href="https://github.com/reactstrap/reactstrap">How it Works</NavLink>
                    </NavItem>
                    <UncontrolledDropdown nav inNavbar>
                      <DropdownToggle nav caret>
                        login/signup
                      </DropdownToggle>
                      <DropdownMenu right>
                        **<DropdownItem onClick={this.loginmodals}>
                          Login
                          <Login loginmodal={this.state.loginmodal} loginmodals={this.loginmodals}/>
                        </DropdownItem>**
                        <DropdownItem divider />
                        <DropdownItem>
                          Reset
                        </DropdownItem>
                      </DropdownMenu>
                    </UncontrolledDropdown>
                  </Nav>
                </Collapse>
              </Navbar>
            </div>
        )
    }
} 
export default NavbarComponent;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM