It should be <div className="dropdown"> instead of <div class="dropdown"> and <div id={styles.myDropdown} className={styles.dropdownContent}>
You would also avoid doing vanilla js inside a react/next app.
You would instead have a react state like this:
const [dropdownToggled, toggleDropdown] = useState(false);
const handleClick = () => {
toggleDropdown(!dropdownToggled);
};
And have a condition on whether your jsx have a className hidden that sets display: none
something like this:
<div
className={`${styles.dropdownContent}
${dropdownToggled ? styles.hidden : ""}`}
>
<a href="/">Link 1</a>
<a href="/">Link 2</a>
<a href="/">Link 3</a>
</div>
To make the dropdown close when the user clicks outside, you would have a div like this:
<div
className={styles.backdrop}
onClick={() => toggleDropdown(true)}
></div>
that is styled like this:
.backdrop {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -1;
}
Now since this div takes the whole screen and is positioned absolute when the user clicks anywhere on the page the onClick will fire and toggle the dropdown.
Working CodeSandbox.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
Open
lekoala opened this issue
Oct 6, 2022
· 15 comments
Comments
Prerequisites
- I have searched for duplicate or closed issues
- I have validated any HTML to avoid common problems
- I have read the contributing guidelines
Describe the issue
I’m having the following issue in production on one website
Cannot read properties of null (reading ‘classList’)
At the lines
| this._element.classList.add(CLASS_NAME_HIDE) // @deprecated | |
| this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW) | |
| EventHandler.trigger(this._element, EVENT_HIDDEN) |
My guess is that the element is already removed when that callback is called (i’m calling .dispose in the bs.hidden callback event I don’t know if that’s related or not. it should work without issues either way in my opinion).
Reduced test cases
My proposal is to simply add a null check before and return early if this._element is null
Demo
https://codepen.io/lekoalabe/pen/oNdPNXJ
click create modal
click create toast
accept sweet alert modal
try to click close icon on toast => it triggers the error
What operating system(s) are you seeing the problem on?
Windows
What browser(s) are you seeing the problem on?
Chrome
What version of Bootstrap are you using?
v5.2.2
Hello @lekoala. Bug reports must include a live demo of the issue. Per our contributing guidelines, please create a reduced test case on CodePen or StackBlitz and report back with your link, Bootstrap version, and specific browser and Operating System details.
ok so it’s kind of hard to replicate but here it goes
it can trigger a variety of errors I’ve listed in the codepen
i have to admit it’s a bit extreme to have sweetalert, modals and toasts all over the place, but it shouldn’t create js error anyway
you have to click around a fair bit to trigger the various error. the toast error is caused like this:
- click create modal
- click create toast
- accept sweet alert modal
- try to click close icon on toast => it triggers the error
ok so it’s kind of hard to replicate but here it goes
it can trigger a variety of errors I’ve listed in the codepen
i have to admit it’s a bit extreme to have sweetalert, modals and toasts all over the place, but it shouldn’t create js error anyway
you have to click around a fair bit to trigger the various error. the toast error is caused like this:
- click create modal
- click create toast
- accept sweet alert modal
- try to click close icon on toast => it triggers the error
This issue is related to #37245
i’m not sure adding null checks will fix the root cause, but at least it would prevent js errors. these errors don’t seem to prevent expected behaviour, so I think it should be pretty safe to add them.
I had a «quick» look to the given codepen.
-
You have imported the
bootstrap.bundle.jstwice, that was causingmodal.js:357 Uncaught TypeError: Cannot read properties of null (reading 'hide') -
plus, I couldn’t spot any referral to
bootstrap.Toast😖

Is a bit strange to find an error on bootstrap toast, without using it. 😵💫
@GeoSot sorry about that indeed i tried a couple of variations and indeed i left a duplicate import. without it i dont have the issue anymore (it still happens (without duplicates) in prod in another app but it’s hard to replicate the exact setup).
not sure why importing twice would break everything though?
I’m using a «toaster» helper method that calls new bootstrap.Toast under the hood, i can extract this helper if that makes anything clearer but in any case, without the duplicate import i didn’t find a way to replicate my issue
For sure, I can try to help only if you use the Bs components explicitly, and not inside another library. It is not possible to guess any side effects
@GeoSot so i managed to replicate it finally!
basically it’s very tricky to get it by hand, which is why it happens rarely
if you click or double click on the close icon right when it’s supposed to close, it may fail
I’ve simulated this with a setTimeout

I tried it a lot in comparison with a ‘native’ toast. On your codepen example, for some reason (not able to debug all these lines 😞), the second click of the double-click, seems, it is finding the event listener still registered, so it tries to execute the hide process twice. In contradiction, this cannot be replicated on a native toast https://getbootstrap.com//docs/5.2/components/toasts/#live-example
So maybe the better scenario is to try to decouple the code a bit, or try to refactor based on the given events
@GeoSot ok fair point i’ve simplified the example even more and I think I found the actual issue:
- if you use autohide
- and you dispose of the instance on hidden
- if someone tries to click on the close icon, you get an error
what do you think? Maybe disposing of the class after hidden is not a good idea?
Soooo I found some time to try your code
Using your script with some minor changes (you will find below), seems, it works ok
const html = `<div id="liveToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true"> <div class="toast-header"> <strong class="me-auto">Bootstrap</strong> <small>11 mins ago</small> <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> </div> <div class="toast-body"> Hello, world! This is a toast message. </div> </div> </div>`; document.getElementById("toast-me").addEventListener("click", ev => { const container = document.getElementById("toast-container"); container.innerHTML = container.innerHTML + html; const toastElList = document.querySelectorAll(".toast"); console.log(toastElList.length); toastElList.forEach(toastEl => { const inst = bootstrap.Toast.getOrCreateInstance(toastEl, { autohide: true }); inst.show(); toastEl.addEventListener( "hidden.bs.toast", () => { // can cause issue with bs5 // @link https://github.com/twbs/bootstrap/issues/37265 inst.dispose(); //toastEl.remove(); console.log(inst, toastEl); }, { once: true } ); }); setTimeout(() => { document.querySelectorAll(".btn-close").forEach((btn) => { btn.dispatchEvent(new Event("click")); console.log("click"); }); }, 5000); });
@GeoSot i updated the pen with your code, it’s still happening. you do have to click a crazy person to get the issue. I suspect there is some kind of race condition happening in rare cases when you click on the close icon (which is what i can gather from the error reporting in my production app)

@GeoSot Got the issue again on another project so i decided to have a look again
good thing is: i know what is the precise, reproducible error and updated the codepen accordingly
it happens if you double click fast on the close icon and if the instance was disposed on hidden callback.
- removing animations fixes the issue => there is no delay in queue callback and therefore, double clicking has no impact
- delaying the dispose with a timeout works also => this is what i will be doing for now

- disabling pointer events on hide also seem to work just fine
therefore, i don’t think there is anything really wrong with bootstrap itself if you don’t dispose of toast instances on hidden. This is still a (minor) issue as soon as you try to create dynamic instances like I do and need to dispose of them afterwards and remove the actual html element from the dom.
in the same line of thinking, you can get similar issue with dynamic models where you get
undefined is not an object (evaluating ‘this._config.backdrop’)
some kind of issue: dispose&removing on hidden can lead to this
Issue
I am having this header which on scroll, I want to change the background to a different color.
The navbar variable returns null always. Why is it so? How can I do that?
The transform:translateY is just for a small animation on scroll.
import React from 'react'
import { Navbar, Container, Nav } from 'react-bootstrap'
import { LinkContainer } from 'react-router-bootstrap'
const Header = () => {
const navbar = document.getElementById("navbar");
let scrolled = false;
window.onscroll = function () {
if (document.body.scrollTop >= 200 || document.documentElement.scrollTop >= 200) {
navbar.classList.add('color-nav');
if (!scrolled) {
navbar.style.transform = 'translateY(-70px)'
}
setTimeout(function () {
navbar.style.transform = 'translateY(0px)'
scrolled = true
}, 200)
} else {
navbar.classList.remove('color-nav');
scrolled = false
}
};
return (
<div id='navbar' >
<Navbar fixed="top" className='navbar' collapseOnSelect expand="lg" >
<Container>
<LinkContainer to='/'>
<Navbar.Brand className='logo' >Logo</Navbar.Brand>
</LinkContainer>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="me-auto">
<LinkContainer to='/services'>
<Nav.Link className='links'>Services</Nav.Link>
</LinkContainer>
</Nav>
<Nav>
<LinkContainer to='/login'>
<Nav.Link className='links'>Login</Nav.Link>
</LinkContainer>
<LinkContainer to='/signup'>
<Nav.Link className='links'>
Sign Up
</Nav.Link>
</LinkContainer>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</div >
)
}
export default Header

You are going about things in what I’d like to call, «against the React way». To access the navbar element, you should be utilizing the useRef hook. This will give you an easy reference to that element through the components lifecycle.
On top of that, there are some other issues that need to be taken care of:
- The
scrolledvariable not being used withuseState - Your scroll listener not being set in a
useEffect. Right now, your code would set a new listener on every re-render of your component. You want to just set it once. - Your scroll listener not being cleaned up.
I’ve made some changes to the code that I would hope will fix this issue for you.
import React, { useState, useRef, useEffect } from "react";
import { Navbar, Container, Nav } from "react-bootstrap";
import { LinkContainer } from "react-router-bootstrap";
const Header = () => {
const [scrolled, setScrolled] = useState(false);
const navRef = useRef();
useEffect(() => {
const handleScroll = () => {
if (
document.body.scrollTop >= 200 ||
document.documentElement.scrollTop >= 200
) {
navRef.current.classList.add("color-nav");
if (!scrolled) {
navRef.current.style.transform = "translateY(-70px)";
}
setTimeout(function () {
navRef.current.style.transform = "translateY(0px)";
setScrolled(true);
}, 200);
} else {
navRef.current.classList.remove("color-nav");
setScrolled(false);
}
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
return (
<div id="navbar" ref={navRef}>
<Navbar fixed="top" className="navbar" collapseOnSelect expand="lg">
<Container>
<LinkContainer to="/">
<Navbar.Brand className="logo">Logo</Navbar.Brand>
</LinkContainer>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="me-auto">
<LinkContainer to="/services">
<Nav.Link className="links">Services</Nav.Link>
</LinkContainer>
</Nav>
<Nav>
<LinkContainer to="/login">
<Nav.Link className="links">Login</Nav.Link>
</LinkContainer>
<LinkContainer to="/signup">
<Nav.Link className="links">Sign Up</Nav.Link>
</LinkContainer>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</div>
);
};
export default Header;
Answered By — Dan Zuzevich
Всем привет. В консоли возникает следующая ошибка «Uncaught TypeError: Cannot read property ‘classList’ of null
at FormValidator._hideInputError (FormValidator.js:45)». Все перепроверил миллион раз, но все без толку. Гляньте, пожалуйста, в чем проблема?
_hideInputError(inputElement) {
const errorElement = this._formElement.querySelector(`.${inputElement.id}-error`);
inputElement.classList.remove(this._config.inputErrorClass);
errorElement.classList.add(this._config.errorClass);
errorElement.textContent = '';
}
весь код класса доступен по ссылке https://codepen.io/azNex/pen/powwQWm
TypeError: Cannot read property ‘classList’ of Null in JavaScript is an error frequently happens to all programmers. Please refer to the document below to avoid making this mistake again.
Why does the error “TypeError: Cannot read property ‘classList’ of Null” in JS happen?
I have carefully observed and studied the error “TypeError: Cannot read property ‘classList’ of Null” in Javascript. It is an error that happens quite often to me. To describe it intuitively, you should look at the following example.
In index.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="LearnShareIT">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title id = "learn">Learn Share IT</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
In main.js file:
const text = document.createTextNode("LearnShareIT");
const add = document.getElementById("lear");
add.appendChild(text);
console.log(text);
First I create an element <title > with id="learn". Then in the main.js file, I wanted to call an element with that id, but I mistyped the id name. So my return value is null. If I stop here, the error won’t happen, but I used it to add the text "LearnShareIT". The null value could not add this text, giving an error.
Output
main.js:132 Uncaught TypeError: Cannot read properties of null (reading 'appendChild')
at main.js:132:5
To fix this error, please refer to some ways below.
How to fix this error?
Get the correct element
Make sure you get the element you want to get. If you can’t get the element, the result will return null, and when you manipulate that data, it will throw an error like this:
const text = document.getElementById("lear");
console.log(text);
Output
null
Please check the id name correctly:
const text = document.getElementById("learn");
console.log(text);
Output
<title id="learn">Title</title>
You can use this element to change the text content, and it will not raise an error:
const text = document.createTextNode("LearnShareIT");
const add = document.getElementById("learn");
add.appendChild(text);
console.log(text);
Output
LearnShareIT
The content of Title has been changed to LearnShareIT.
Put the main.js file in the correct location
Misplacing your js file can also affect the results. If the file is misplaced, it will not run and the return result will be null. It will repeat the above error if it is used to manipulate methods inside Javascript.
Make sure your file is located in the body tag as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="LearnShareIT">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title id = "learn">Learn Share IT</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
Output
LearnShareIT
Summary
To avoid the error “TypeError: Cannot read property ‘classList’ of Null” in JS, make sure that the value you get is not null. The article showed two ways to handle it, let’s follow to solve your project.
Maybe you are interested:
- TypeError: Cannot read property ‘top’ of Undefined in JS
- TypeError: Cannot set properties of Undefined in JavaScript
- TypeError: Converting circular structure to JSON in JS
- TypeError: filter is not a function in JavaScript

My name is Tom Joseph, and I work as a software engineer. I enjoy programming and passing on my experience. C, C++, JAVA, and Python are my strong programming languages that I can share with everyone. In addition, I have also developed projects using Javascript, html, css.
Job: Developer
Name of the university: UTC
Programming Languages: C, C++, Javascript, JAVA, python, html, css
