Search code examples
javascriptreactjsreact-modal

Modal not activating due to Prop


I am having some trouble activating a modal by passing in a toggling modal method from inside a class component. I have my navigation bar as my functional component and the state in the class component at the bottom. It seems like they are connected but the onClick isn't seem to be activating my modal. Is anyone able to help me see what is going on? I thought biinding the method with the state will allow it to be accessible and pass as a prop, therefore onClick={props.modal.toggleModal below, in my opinion would change the state to "true"?

function NavigationBar(props){
    return(
        <React.Fragment>
            
            <Navbar dark sticky="top" expand="md">
                <div className="container">
                    <NavbarBrand className="mr-auto"><img src="../images/compLogo.jpg" width="30" height="30" alt="company logo"/></NavbarBrand>
                    <NavbarToggler />
                    <Collapse navbar>
                        <Nav navbar>
                      

                        
                            <Button className="nav-link buttonModal" onClick={props.modal.toggleModal}>
                                 <i className="fa fa-address-book fa-lg" /> Contact Us
                            </Button>
                            
                        
                        </Nav>
                    </Collapse>
                </div>
            </Navbar>


           <--Modal-->

            <Modal isOpen={props.modal.isModalOpen} toggle={props.modal.toggleModal}>
                <ModalBody>
                    <Form>
                        <FormGroup>
                            <Label htmlFor="name">Name</Label>
                            <Input type="text" />
                        </FormGroup>
                    </Form>
                </ModalBody>
            </Modal>
            
        </React.Fragment>
    )
}

class Header extends Component {
    constructor(props){
        super(props);
            this.state={
                isModalOpen: false
            }
            
            this.toggleModal = this.toggleModal.bind(this);
        }

    toggleModal(){
        this.setState({isModalOpen: !this.state.isModalOpen})
    }

    render(){
        return(
            <NavigationBar modal={this.state}/>
        )
    }
}

export default Header;


Solution

  • Only the state is passed to the modal

    <NavigationBar modal={this.state}/>
    

    But you should pass both the isModalOpen state and the toggleModal callback. I suggest passing them individually for readability and maintenance.

    class Header extends Component {
      constructor(props) {
        super(props);
        this.state = {
          isModalOpen: false
        };
    
        this.toggleModal = this.toggleModal.bind(this);
      }
    
      toggleModal() {
        this.setState({ isModalOpen: !this.state.isModalOpen });
      }
    
      render() {
        return (
          <NavigationBar
            isModalOpen={this.state.isModalOpen}
            toggleModal={this.toggleModal}
          />
        );
      }
    }
    

    Modal

    function NavigationBar(props) {
      return (
        <React.Fragment>
          <Navbar dark sticky="top" expand="md">
            <div className="container">
              <NavbarBrand className="mr-auto">
                <img
                  src="../images/compLogo.jpg"
                  width="30"
                  height="30"
                  alt="company logo"
                />
              </NavbarBrand>
              <NavbarToggler />
              <Collapse navbar>
                <Nav navbar>
                  <Button
                    className="nav-link buttonModal"
                    onClick={props.toggleModal} // <-- access props.toggleModal
                  >
                    <i className="fa fa-address-book fa-lg" /> Contact Us
                  </Button>
                </Nav>
              </Collapse>
            </div>
          </Navbar>
    
          <Modal
            isOpen={props.isModalOpen} // <-- access props.isModalOpen
            toggle={props.toggleModal} // <-- access props.toggleModal
          >
            <ModalBody>
              <Form>
                <FormGroup>
                  <Label htmlFor="name">Name</Label>
                  <Input type="text" />
                </FormGroup>
              </Form>
            </ModalBody>
          </Modal>
        </React.Fragment>
      );
    }