I am trying to use Google's Material Design Lite with ReactJS. I am using Spinner Loading & Text Field Component of MDL library.
But, when I switch routes with React Router, the animation does not take place & when I refresh the page, it works fine. I think, this is probably because MDL components are not getting upgraded. Then, I am trying to use componentHandler.upgradeDom()
, but Console throws an error, app.js:27160 Uncaught TypeError: Cannot read property 'upgradeDom' of undefined
.
Here is the code,
var React = require('react'); var ReactDOM = require('react-dom'); var PropTypes = React.PropTypes; var MDLite = require('material-design-lite'); var componentHandler = MDLite.componentHandler; var styles = { loader: { marginTop: '70px', } } var Loading = React.createClass({ render: function() { return ( <div className="mdl-spinner mdl-js-spinner is-active" style={styles.loader}></div> ); }, componentDidMount: function() { componentHandler.upgradeDom(); }, }); module.exports = Loading;
I also tried to log MDLite variable in Console with console.log(MDLite)
. But, it is showing me an empty Object {}. I am using webpack & have installed Material Design Lite with NPM, npm install material-design-lite --save
.
My question is how can I import/require MDL properly & use componentHandler.upgradeDom()
?
I figured out the solution myself. There are two ways through which you can achieve this.
The Lazy Way
In node_modules/material-design-lite/material.js
, edit & add the following code in the end as mentioned below.
// You can also export just componentHandler if (typeof module === 'object') { module.exports = window; }
Your material.js file will look like this.
;(function() { . . . componentHandler.register({ constructor: MaterialRipple, classAsString: 'MaterialRipple', cssClass: 'mdl-js-ripple-effect', widget: false }); // You can also export just componentHandler if (typeof module === 'object') { module.exports = window; } }());
In your React Component file, require
like this,
var MDLite = require('material-design-lite/material'); var componentHandler = MDLite.componentHandler;
Then, you can call componentHandler.upgradeDom()
to upgrade MDL elements.
Note that you can also write module.exports = componentHandler;
if you only want to import componentHandler
.
The Webpack Way
Personally, I would prefer the webpack way as it is much cleaner & you need not to edit the module files yourself.
Install exports-loader, npm install exports-loader --save-dev
. Then, in your webpack.config.js, specify loaders as
loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'exports-loader!babel-loader' } ]
In your React Component file, you can require
componentHandler as
var componentHandler = require('exports?componentHandler!material-design-lite/material');
I hope it helps!