How to use materialize-css with React?

2019-01-21 23:17发布

问题:

I have a Meteor/React project, using ES6 modules. I've installed materialize-css using npm, but I'm not sure how to actually use the Materialize classes in my JSX code. What am I supposed to import from materialize-css? Or do I just have to include the CSS in my main index.html file?

I mostly want it for the grid system, as I'll be using material-ui for the actual UI components.

回答1:

Since I use CSS Modules, importing materialize css would scope it to that particular component. So I did the following

Step 1) install materialise

npm install materialize-css@next 

Step 2) in index.html

<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.3/css/materialize.min.css">

Step 3) import materialise.js in whichever component its needed

for e.g. in SomeComponent.js (for e.g. if this is about a sidenav)

import React from 'react';
import M from 'materialize-css';
....
// ref can only be used on class components
class SomeComponent extends Component {
  // get a reference to the element after the component has mounted
  componentDidMount(){
    M.Sidenav.init(this.sidenav);
  }

  render(){
    return (
      <ul className={this.props.classes}
          ref={ (sidenav) => {this.sidenav = sidenav} }
          id={this.props.id}>
        // menuItems
      </ul>
    )
  }
}

just a beginner, so I would appreciate any comments on downsides of this method



回答2:

There are possible ways that I can recommend to use:

  1. One way is just include your stylesheet file in index.html and use className property in your React components just like this.

        var myDivElement = <div className="foo" />;
        ReactDOM.render(myDivElement, document.getElementById('example'));
    
  2. Another way is to bundle all your stylesheeets in one stylesheet file and to use them as previous one.

  3. One option could be to use webpack. By using webpack, it is possible to use embedded stylesheets in jsx files just by requiring stylesheet that you want to include.

    require("./stylesheet.css")

    To examine in detail webpack stylesheet option: http://webpack.github.io/docs/stylesheets.html

  4. Also see JedWatson's classnames repo for conditional className usage. https://github.com/JedWatson/classnames


回答3:

With NPM:

Step 1: Install materialize

If you are using npm, make sure you install materialize using the command listed in their documentation:

npm install materialize-css@next 

DON'T MISS the '@next' at the end. The installed version will be something like: "^1.0.0-rc.2" OR "^1.0.0-alpha.4"

Step 2: Import materialize:

import 'materialize-css/dist/css/materialize.min.css'

import M from 'materialize-css/dist/js/materialize.min.js'

OR

import 'materialize-css/dist/css/materialize.min.css'

import M from 'materialize-css'

In order for the css import to work, you would need a css loader. Note that this loader is already included in projects built using create-react-app so you don't need the next steps. If instead, you are using custom webpack config, then run:

npm install --save-dev style-loader css-loader

Now add css-loader and style-loader in webpack config

const path = require("path");

module.exports = {
    entry: "./src/index.js",
    output: {
        filename: "bundle.js",
        path: path.join(__dirname, "build")
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /.js$/,
                exclude: /(node_modules)/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ["env", "react"]
                    }
                }
            }
        ]
    }
}

Now you can initialize components individually, or all at once using M.AutoInit();


With CDN:

Add the following in your HTML file.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.min.js"></script>

Then, in the webpack config, add externals: https://webpack.js.org/configuration/externals/



回答4:

You can use https://react-materialize.github.io/#/, why to reinvent the wheel.

installation react-materialize

npm install react-materialize

Usage

import {Button, Icon} from 'react-materialize'

export default () => (
  <Button waves='light'>
    <Icon>thumb_up</Icon>
  </Button>
)

Sample

https://github.com/hiteshsahu/react-materializecss-template

Screenshot



回答5:

You can copy into "imports" folder and add by

import '../imports/stylesheets/materialize.min.css';

or use this for LESS example

@import '{}npm-package-name/stylesheets/...';


回答6:

These answers didn't satisfy my biggest concern which was bundle size and importing a ton of code in order to use a few components. I've written up a solution here that includes code splitting and an easy compilation step.

The key points are:

  1. Compile base JS files (there are 4)
  2. Ensure the base JS is included before your imports / bundler runs
  3. Change the CSS imports to only what you need
  4. Run materialize.scss through your bundler if it supports Sass or run the compilation step to get a minified css file.
  5. Import individual components and activate them manually

Read post for more details.