Materialize: Animations on inputs get lost when rending using React

Created on 13 Apr 2015  路  6Comments  路  Source: Dogfalo/materialize

  • Materialize-CSS & jQuery are referenced via cdnjs
  • Regular HTMLs are working fine as below (underline & floating effects)
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/materialize/0.96.1/css/materialize.min.css">
  <link href="//fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet" type="text/css">
</head>
<body>

  <div class="row">
    <main id="main" class="container">
      <form id="login" class="col s6">
        <div class="row">
          <div class="input-field col s6">
            <input id="last_name" type="text" />
            <label for="last_name">Last Name</label>
          </div>
        </div>
      </form>
    </main>
  </div>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/materialize/0.96.1/js/materialize.min.js"></script>

Once I tried rendering the form/inputs via React, all those related animations gone, & the label placed right under the input element, exactly the same as where they originally defined.

  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/materialize/0.96.1/css/materialize.min.css">
  <link href="//fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet" type="text/css">
</head>
<body>

  <div class="row">
    <main id="main" class="container"></main>
  </div>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/materialize/0.96.1/js/materialize.min.js"></script>
<script src="//localhost:8000/webpack-dev-server.js"></script>
<script src="//localhost:8000/app.js"></script>

webpack.config.js

var webpack           = require("webpack");
var devserver         = "http://localhost:8000/";
var HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: [
    "webpack/hot/dev-server",
    "./app.jsx"
  ],

  externals: {
    "jquery": "jQuery",
    "materialize": "materialize"
  },

  devServer: {
    info: false,
    hot: true,
    inline: true,
    port: 8000,
    host: "localhost",
    colors: true,
    progress: true,
    historyApiFallback: true,
    stats: {
      colors: true,
      progress: true
    },
  },

  output: {
    path: __dirname + "/build/",
    publicPath: devserver,
    filename: "app.js"
  },

  resolve: {
    extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx']
  },

  module: {
    loaders: [
      { test: /\.eot$/,  loader: "file-loader" },
      { test: /\.woff2?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
      { test: /\.ttf$/,  loader: "url-loader?limit=10000&mimetype=application/octet-stream" },
      { test: /\.svg$/,  loader: "url-loader?limit=10000&mimetype=image/svg+xml" },

      { test: /\.css$/,   loader: 'style!css!autoprefixer'},
      { test: /\.scss$/,  loader: 'style!css!autoprefixer!sass'},
      { test: /\.jsx$/,   loader: 'react-hot!babel-loader?stage=0', exclude: /node_modules/ }
    ]
  },

  plugins: [
    new HtmlWebpackPlugin({
      title: "Index",
      template: "assets/index.html",
      assets: {
        app: "//localhost:8000/app.js"
      }
    }),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin(),
  ]
};

app.jsx

(function () {
  require("react-tap-event-plugin")();

  React.render(
      <form id="login" class="col s6">
        <div class="row">
          <div class="input-field col s6">
            <input id="last_name" type="text" />
            <label for="last_name">Last Name</label>
          </div>
        </div>
      </form>
, document.getElementById("main"));
})();

Most helpful comment

How do you import Materialize into the React component? When I try to put Materialize.updateTextFields() into componentDidMount(), it throws an error saying Materialize is undefined.

All 6 comments

You can alleviate this particular issue by calling Materialize.updateTextFields() in your React component's componentDidMount().

But this is a big hammer to hit to get Materialize to work with React. By calling Materialize.updateTextFields(), each component essentially end up going over each input field on the whole page and applying Materialize magic for each. Even after doing this, you will see that text area components don't behave correctly (I am filing an issue for this and others).

replace class with className and for with htmlFor

Calling Materialize.updateTextFields() within componentDidMount() worked for me. Thanks.

Materialize.updateTextFields() should work, or you can add class="active"

How do you import Materialize into the React component? When I try to put Materialize.updateTextFields() into componentDidMount(), it throws an error saying Materialize is undefined.

@Dogfalo how do you get the label to use className="active" if the input is focused? And we need to remove that after it is blurred.

Was this page helpful?
0 / 5 - 0 ratings