Search code examples
javascriptcssnode.jsreactjsmaterialize

Using React.JS with Materialize v1.0.0 unable to init JS


Been trying to convert several of our projects using materialize-css v1.0 using npm into react.js and having a heck of time doing so. I was wondering if anyone else has tried to tackle this as well and maybe came up with some solutions?

I am able to use the css portion just fine using the npm module and referencing it in the Index.js.

The problem I have is initializing the minified js with individual components but having no success. Here is the example one being the Index.js for css entry point and the sidebar component I am trying to get working using minified js. I also provided the App.js configuration in case anyone was curious. The plan was to break each part of this project into individual components but first just wanted to get the functionality of initializing the sidebar js first before doing so.

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import 'materialize-css/dist/css/materialize.min.css';
import App from './components/App';
ReactDOM.render(<App />, document.getElementById('root'));

App.js

import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
// import Header from './header/Header';
// import Footer from './Footer';
import Landing from './landing/Landing';
import About from './About';
import Projects from './Projects';
class App extends Component {
 render() {
 return (
 <div>
 <BrowserRouter>
 <div>
 {/*<Header />*/}
 <Route exact path="/" component={Landing} />
 <Route exact path="/about" component={About} />
 <Route exact path="/projects" component={Projects} />
 {/*<Footer /> */}
 </div>
 </BrowserRouter>
 </div>
 );
 }
}
export default App;

Landing.js

import React, { Component } from 'react';
import M from 'materialize-css/dist/js/materialize.min.js';
// import { Link } from 'react-router-dom';
import './Landing.css';

class Landing extends Component {
  componentDidMount() {
    console.log(M);
    const sideNav = document.querySelector('.button-collapse');
    console.log(M.Sidenav.init(sideNav, {}));

    M.Sidenav.init(sideNav, {});
  }

  render() {
    return (
      <div className="main-header">
        <div className="primary-overlay">
          <div className="navbar-fixed">
            <nav className="transparent">
              <div className="container">
                <div className="nav-wrapper">
                  <a href="#home" className="brand-logo">
                    TEST
                  </a>
                  <a data-activates="side-nav" className="button-collapse">
                    <i className="material-icons">menu</i>
                  </a>

                  <ul className="right hide-on-med-and-down">
                    <li>
                      <a href="#home">Home</a>
                    </li>
                    <li>
                      <a href="#about">About</a>
                    </li>
                    <li>
                      <a href="#testimonials">Testimonials</a>
                    </li>
                    <li>
                      <a href="#contact">Contact</a>
                    </li>
                    <li>
                      <a className="btn blue">Download</a>
                    </li>
                  </ul>
                </div>
              </div>
            </nav>
          </div>

          {/* Side Nav: fixed navbars must go right underneath main nav bar */}
          <ul id="side-nav" className="side-nav">
            <h4 className="blue-grey darken-4 center">TEST</h4>
            <li>
              <a className="divider" />
            </li>
            <li>
              <a href="#home">Home</a>
            </li>
            <li>
              <a href="#about">About</a>
            </li>
            <li>
              <a href="#testimonials">Testimonials</a>
            </li>
            <li>
              <a href="#contact">Contact</a>
            </li>
          </ul>

          {/*-- Showcase */}
          <div className="showcase container">
            <div className="row">
              <div className="col s12 main-text">
                <h5>You found the...</h5>
                <h1>Right Place To Start</h1>
                <p className="flow-text">
                  To take your business to the next level with our services that
                  have taken companies to the fortune 500
                </p>
                <a href="#about" className="btn btn-large white black-text">
                  Learn More
                </a>
                <a href="#contact" className="white-text">
                  <i className="material-icons medium scroll-icon">
                    arrow_drop_down_circle
                  </i>
                </a>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default Landing;

Here are some screen shots I am getting with errors in my console as well regarding the anchor tags (not sure how I work around this if its needed in the side bar). I am getting access to the sidebar as per the console.logs shown below.

enter image description here

enter image description here

​Hope someone else has encountered this problem already and can help...

Cheers!

[![enter image description here][3]][3]


Solution

  • The trigger button markup is incorrect. It has to be data-target and it has to have the class sidenav-trigger. Also the side nav has to have the classname sidenav. side-nav with a hyphen will not work:

    <a href="#" data-target="side-nav" className="sidenav-trigger button-collapse">
        <i className="material-icons">menu</i>
    </a>
    

    Also you should always use refs instead of querying the DOM yourself when working with react. Apply a ref callback to the sidenav element and then use it to initialize:

    class Landing extends Component {
        onRef = nav => {
            this.nav = nav;
            M.Sidenav.init(nav);
        };
    
        render() {
            return (
               {/* ... */}
    
                <ul ref={this.onRef} id="side-nav" className="sidenav">
                    <li><a className="divider" /></li>
    
                    {/* ... */}
                </ul>
    
                {/* ... */}
            );
        }
    }
    

    Working example with your corrected markup:

    Edit xllp3wrnvo