using componentDidMount() to initialize materialize js works fine as shown in the documentation
componentDidMount() {
document.addEventListener("DOMContentLoaded", function() {
var elems = document.querySelectorAll(".sidenav");
M.Sidenav.init(elems, {});
});
}
but whenever I convert my component to a functional one and run the same initialization inside useEffect it doesn't work and my sideNav isn't initialized
the whole code
import React, { Fragment, useEffect } from "react";
import M from "materialize-css/dist/js/materialize.min.js";
export const Navbar = () => {
useEffect(() => {
document.addEventListener("DOMContentLoaded", function() {
var sidenav = document.querySelectorAll(".sidenav");
M.Sidenav.init(sidenav, {});
});
}, []);
return (
<Fragment>
<div className="navbar-fixed">
<nav className="teal darken-3">
<div className="nav-wrapper mx-4">
<a href="#!" className="brand-logo">
<i className="far fa-id-badge" />
EMS
</a>
<a href="#!" className="sidenav-trigger" data-target="mobile-nav">
<i className="material-icons">menu</i>
</a>
<ul className="right hide-on-med-and-down">
<li>
<a href="profiles.html">Settings</a>
</li>
<li>
<a href="register.html">Register</a>
</li>
<li>
<a href="login.html">Login</a>
</li>
</ul>
</div>
</nav>
</div>
<ul className="sidenav blue-grey darken-4" id="mobile-nav">
<h3 className="teal-text ml-2">EMS</h3>
<li>
<div className="divider blue-grey darken-2"></div>
</li>
<li>
<a href="profiles.html" className="white-text">
Settings
</a>
</li>
<li>
<a href="register.html" className="white-text">
Register
</a>
</li>
<li>
<a href="login.html" className="white-text">
Login
</a>
</li>
</ul>
</Fragment>
);
};
i think the issue is with the document.addEventListner
you should know when you just want to useEffect works like componentDidMount you should pass empty array as the second parameter. like below
useEffect(() => {
var sidenav = document.querySelectorAll(".sidenav");
M.Sidenav.init(sidenav, {});
}, []);
in this way useEffect only run once. and notice : when componentDidMount fires it means all HTML is already in the DOM. so you don't need any listener for data fully loaded.
and please note that effects in react are just effects, do not think them as lifecycles.