I'm new to React and I am trying to build a standalone Header component containing a 'slide in sidebar'. I used state to apply CSS to slide the sidebar in/out:
constructor() {
super();
this.state = {
sideBar: false
}
}
handleSidebar() {
this.setState({
sideBar: !this.state.sideBar
});
}
render() {
return(
<header>
<ul style={this.state.sideBar ? {'transform': 'translateX(0%)'} : null}></ul>
<button onClick={this.handleSidebar.bind(this)}></button>
</header>
)
This does the job in terms of sliding the sidebar, but once the sidebar is open, I would like to lock scroll on body by applying overflow:hidden
to the <body>
. However since <body>
is outside of React, I was wondering how it's possible to access the tag?
Link to Codepen
We can access the body element on the document object. You can use the style object to read an element's styles or set new styles on the element. If you need to add a class to the body element, use the classList. add method.
To add a class to the body element in React: Access the body element as document. body in useEffect or an event handler.
In React we can access the DOM element using Refs. Refs provide a way to access DOM nodes or React elements created in the render method. Creating Refs: Refs are created using React. createRef() and attached to React elements via the ref attribute.
Any property attached to the window object can be accessed from any script on the web page, including the script for the React app. Since window is a global object, the React code can also access its properties, as shown below.
Use document.body
to set the styles you need. Make sure you access document
after it's ready, so put the code in componentWillMount
. You should reset the styles after unmounting the component in componentWillUnmount
.
componentWillMount() {
document.body.style.overflow = "hidden";
}
componentWillUnmount() {
document.body.style.overflow = "visible"; // or restore the original value
}
After your comment I realized that you need to set the styles after opening the sidebar. Here some notes:
this.state
in setState
. setState
is asynchronous, therefore you should use the optional prevState
parameter to access the previous state object. setState
which is a function and is called after the state is updated. In this function you could set the styles of the body.bind
the function in the constructor.props
to the base constructor (super(props)
).sideBar
to isSideBarOpen
. It is a more descriptive name.Here is the final code:
constructor(props) {
super(props);
this.state = {
isSideBarOpen: false
};
this.toggleSideBar.bind(this);
}
updateBodyStyles() {
if (this.state.isSideBarOpen) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "visible";
}
}
toggleSideBar() {
this.setState((prevState) => {
return { isSideBarOpen: !prevState.isSideBarOpen }
}, this.updateBodyStyles);
}
render() {
return (
<header>
<ul style={this.state.isSideBarOpen? {'transform': 'translateX(0%)'} : null}></ul>
<button onClick={this.toggleSideBar}></button>
</header>
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With