Search code examples
reactstrap

reactstrap close Nav when link clicked


I'm sure this has been asked before however, I can't find the answer. How do you get the Nav menu to close when you click on a NavLink in reactstrap or is this still in development?


Solution

  • Reactstrap has an isOpen parameter in state, so you need to set it to false

        constructor(props) {
            super(props);
    
            this.closeNavbar = this.closeNavbar.bind(this);
            this.state = {
                isOpen: false
            };
        }
    
        closeNavbar() {
            this.setState({
                isOpen: false
            });
        }
    
        // and in Link or a element add onClick handler like this
    
    
        <Link to="/" onClick={closeNavbar}>Home</Link>
    

    Here is the code I use:

    import React, { Component } from 'react';
    import { Link } from 'react-router-dom';
    import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
    import library from './FontAwesomeLibrary';
    import logo from '../../assets/images/logo.svg';
    
    import {
        Collapse,
        Navbar,
        NavbarToggler,
        Nav,
        NavItem } from 'reactstrap';
    
    class Topbar extends Component {
        constructor(props) {
            super(props);
    
            this.toggle = this.toggle.bind(this);
            this.closeNavbar = this.closeNavbar.bind(this);
            this.handleClickOutside = this.handleClickOutside.bind(this);
    
            this.state = {
                isOpen: false,
            };
        }
        componentWillMount() {
            document.addEventListener('mousedown', this.handleClickOutside);
        }
        componentWillUnmount() {
            document.removeEventListener('mousedown', this.handleClickOutside);
        }
    
        toggle() {
            this.setState({
                isOpen: !this.state.isOpen
            });
        }
        closeNavbar() {
            this.setState({
                isOpen: false
            });
        }
        handleClickOutside(event) {
            const t = event.target;
            if (this.state.isOpen && !t.classList.contains('navbar-toggler')) {
                this.closeNavbar();
            }
        }
    
        render() {
            return (
                <div className="topbar">
                    <section className="container">
                        <Navbar color="light" className="header" expand="md">
                            <Link className="locoLink" to="/"><img src={logo} className="logo" alt="logo" /></Link>
                            <Link to="/" className="logoCompany">Redux Blog</Link>
                            <NavbarToggler onClick={this.toggle}>
                                <FontAwesomeIcon icon={this.state.isOpen ? "times" : "bars"}/>
                            </NavbarToggler>
                            <Collapse isOpen={this.state.isOpen} navbar>
                                <Nav className="ml-auto routes" navbar>
                                    <NavItem>
                                        <Link to="/" onClick={this.closeNavbar}>Posts</Link>
                                    </NavItem>
                                    <NavItem>
                                        <Link to="/posts/new" onClick={this.closeNavbar}>New Post</Link>
                                    </NavItem>
                                </Nav>
                            </Collapse>
                        </Navbar>
                    </section>
                </div>
            );
        }
    }
    
    export default Topbar;
    

    It also handles outside clicks.

    FontAwesomeLibrary

    import { library } from '@fortawesome/fontawesome-svg-core';
    import { faCoffee } from '@fortawesome/free-solid-svg-icons';
    import { faMugHot } from '@fortawesome/free-solid-svg-icons';
    import { faTimes } from '@fortawesome/free-solid-svg-icons';
    import { faBars } from '@fortawesome/free-solid-svg-icons';
    import { faChevronUp } from '@fortawesome/free-solid-svg-icons';
    
    library.add(faCoffee);
    library.add(faMugHot);
    library.add(faTimes);
    library.add(faBars);
    library.add(faChevronUp);
    
    export default library;
    

    I created FontAwesomeLibrary according to https://fontawesome.com/how-to-use/on-the-web/using-with/react