Ben Swindells
Ben Swindells

Reputation: 269

Sidebar DOM overlaps Navbar, removing it from the DOM

Hi im using React to create a sidebar when the user clicks on a burger menu, the problem is when the user clicks on the burger menu, the sidebar appears but the navbar disappears, how do I render both the navbar and the sidebar without overlaying one another?

var app = document.getElementById('app');

class Navbar extends React.Component {
    constructor(props) {
        super(props);
        this.state = { 
            sidebarOn: false
        };
        this.onClickOpen = this.onClickOpen.bind(this);
    }
    
    onClickOpen(open) {
        console.log(open);
        if(open) {
            this.setState({sidebarOn: open});
            Menu();
        }
        
    }
    render() {
        return(
            <div>
            <header>    
            <nav class="navbar navbar-custom sticky-top">
                <a class="navbar-brand" href="#">TO DO LIST</a>
                <a class="burger-menu" href="#"><img src='/images/hamburger-icon.png' onClick={() => this.onClickOpen(true)}></img></a>
            </nav>
            </header>
        </div>
        );
    }
}



function Menu() {
    class Parent extends React.Component {
        constructor() {
            super();
            this.state = {
                burgerOn: "burger-right"
            };
        }
      render() {
        return (
            <div class={this.state.burgerOn}>
                      <div class="container">
                <form >
                    <div class="form-group task-title">
                    <label for="title">
                        Task Title
                    </label>
                    <input type="title" class="form-control" placeholder="Enter Task Title"></input>
                    </div>
                    <div class="form-group task-desc">
                        <label for="desc">Task Description</label>
                        <textarea type="text" class="form-control" id="desc" placeholder="Enter Task Description" rows="5"></textarea>
                    </div>
                </form>
                <div>
                <button type="button" class=" task-btn btn btn-primary">Create</button>
                </div>
                </div>
            </div>
        );
      } 
    }
    ReactDOM.render(<Parent />, app);
}

ReactDOM.render(<Navbar />, app);
var app = document.getElementById('app');

class Navbar extends React.Component {
    constructor(props) {
        super(props);
        this.state = { 
            sidebarOn: false
        };
        this.onClickOpen = this.onClickOpen.bind(this);
    }
    
    onClickOpen(open) {
        console.log(open);
        if(open) {
            this.setState({sidebarOn: open});
            Menu();
        }
        
    }
    render() {
        return(
            <div>
            <header>    
            <nav class="navbar navbar-custom sticky-top">
                <a class="navbar-brand" href="#">TO DO LIST</a>
                <a class="burger-menu" href="#"><img src='/images/hamburger-icon.png' onClick={() => this.onClickOpen(true)}></img></a>
            </nav>
            </header>
        </div>
        );
    }
}



function Menu() {
    class Parent extends React.Component {
        constructor() {
            super();
            this.state = {
                burgerOn: "burger-right"
            };
        }
      render() {
        return (
            <div class={this.state.burgerOn}>
                      <div class="container">
                <form >
                    <div class="form-group task-title">
                    <label for="title">
                        Task Title
                    </label>
                    <input type="title" class="form-control" placeholder="Enter Task Title"></input>
                    </div>
                    <div class="form-group task-desc">
                        <label for="desc">Task Description</label>
                        <textarea type="text" class="form-control" id="desc" placeholder="Enter Task Description" rows="5"></textarea>
                    </div>
                </form>
                <div>
                <button type="button" class=" task-btn btn btn-primary">Create</button>
                </div>
                </div>
            </div>
        );
      } 
    }
    ReactDOM.render(<Parent />, app);
}

ReactDOM.render(<Navbar />, app);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.min.js"></script>
<!DOCTYPE html>
<html>
<head> 
        <script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>   
        <div id="app"></div>
        <script type="text/babel" src="/js/app.js"></script>    
</body>
</html>

enter image description here

enter image description here

As the snipped shows, if you click on the broken image link my form will overwrite the todolist navbar.

Many thanks for the constructive help :)

Upvotes: 2

Views: 101

Answers (2)

Ben Swindells
Ben Swindells

Reputation: 269

I was able to fix my Question by the help from a_m_dev then added a conditional statement to check if the class was open or not, like so:

        class App extends React.Component {
        render() {
            return(
                <div>
                    <Navbar/>
                </div>
            );
        }
    }


    class Navbar extends React.Component {
        constructor() {
            super();
            this.state = {
                burgerOn: false
            }
        }
        clickHandler(open) {
            this.setState({burgerOn: open});
        }
        render() {
            return(
                <div>
                <header>    
                <nav class="navbar navbar-custom sticky-top">
                    <a class="navbar-brand" href="#">TO DO LIST</a>
                    <a class="burger-menu" href="#"><img src='/images/hamburger-icon.png' onClick={() => this.clickHandler(true)}></img></a>
                </nav>
                </header>
                <div>
                    {this.state.burgerOn ? <Parent/> : null}
                </div>
            </div>

            );
        }
    }

    class Parent extends React.Component {

        constructor() {
            super();
            this.state = {
                burgerOn: "burger-right"
            };
        }
        render() {
        return (
            <div class={this.state.burgerOn}>
                      <div class="container">
                <form >
                    <div class="form-group task-title">
                    <label for="title">
                        Task Title
                    </label>
                    <input type="title" class="form-control" placeholder="Enter Task Title"></input>
                    </div>
                    <div class="form-group task-desc">
                        <label for="desc">Task Description</label>
                        <textarea type="text" class="form-control" id="desc" placeholder="Enter Task Description" rows="5"></textarea>
                    </div>
                </form>
                <div>
                <button type="button" class=" task-btn btn btn-primary">Create</button>
                </div>
                </div>
            </div>
        );
      }
    }




ReactDOM.render(<App/>, app);

I hope this helps someone with the same issue :)

Upvotes: 0

amdev
amdev

Reputation: 7460

the problem is that when you want to render the sidebar menu you are using this code

ReactDOM.render(<Parent />, app);

it means that just insert what ever the component is inside of app element in your html file. the result would be like wiping out the previously rendered component and the render the new one. so that is what you see right here:

...some code
          } 
        }
        ReactDOM.render(<Parent />, app); <---- here
    }

    ReactDOM.render(<Navbar />, app); <---- and here

... morecode

you dont need to render what every component you just created inside of root element directly. you only need to render the most upper component ONCE in it all of other components should be nested within the parent one, by that way you only would render one parent component inside of the root element from html file and all other components would be included in it by importing them inside your parent component and using them there, like below:

import React from 'react'
import ReactDOM from 'react-dom'

import B from './B'

class A extends React.component {
   render() {
     return(
       <div>
         <B />
       </div>
     )
   }
}


ReactDOM.render(
  <A />,
  document.querySelector('#app')
)

Upvotes: 1

Related Questions