How do I get the Materialize select dropdown to work with React?

12,919

Solution 1

The solution to this is to use browser default as the class name.

<div class="input-field col s12">
  <select className="browser-default">
    <option value="" disabled selected>Choose your option</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
    <option value="3">Option 3</option>
  </select>
  <label>Materialize Select</label>
</div>

Solution 2

Added M.AutoInit() in componentDidMount() worked !

componentDidMount() {
    console.log("component did mount");
    M.AutoInit();
}

Solution 3

You need to make a few adjustments to get this working.

First, import react-dom.

import ReactDOM from 'react-dom';

Second, add the componentDidMount lifecycle method before the render method in your component. This uses react-dom to grab the select element by way of a ref you supply named 'dropdown', then uses jQuery method noted by Sanath above.

componentDidMount() {
  var element = ReactDOM.findDOMNode(this.refs.dropdown)

  $(element).ready(function() {
    $('select').material_select();
  });
}

render() {
...

Third, add the code to your component. Also, note:

  1. 'selected' was removed from the first option element,
  2. a ref named 'dropdown' was added to the select element,
  3. className is used instead of class (it's a React thing).
render() {
  return (
    <div className="input-field col s12">
      <select ref="dropdown" defaultValue="1">
        <option value="" disabled>Choose your option</option>
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
        <option value="3">Option 3</option>
      </select>
      <label>Materialize Select</label>       
    </div>
  );
}

Last, if you're using webpack, you need to use the webpack.ProvidePlugin to point some specific methods at jQuery.

var webpack = require("webpack");

module.exports = {
...
plugins: [
  new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery",
      "Hammer": "hammerjs/hammer",
      createDayLabel: "jquery",
      createWeekdayLabel: "jquery",
      activateOption: "jquery",
      leftPosition: "jquery"
  })
]

Reload webpack / server and you're good to go.

Solution 4

First try to import M from Materializecss:

import M from 'materialize-css';

As mentioned above adding M.AutoInit() in componentDidMount() works perfectly.

componentDidMount() {
    M.AutoInit();
    ...
} 

But the purpose of writing this answer is because in my case i am changing the state so that i can show/hide some elements, and my <select> tag is hidden when render() executes for the first time. So it would be safe if you add also:

componentDidUpdate() {
  M.AutoInit();
  ...
}

Adding M.AutoInit() in componentDidUpdate() is a must when you show/hide elements.

Solution 5

Another way to do this would be to import { Input } from 'react-materialize'. The code may look something like this:

<Input s={12} 
name={props.name} 
type='select' 
label={props.label} 
defaultValue={props.content}
onChange={props.handlerFunction}>
    {selectorOptions}
</Input>

with selectorOptions as a simple array of JS Objects such as:

let selectorOptions = props.options.map( (option, index) => {
 return (
    <option key={index} value={Object.keys(option)[0]}>
       {Object.values(option)[0]}
    </option>
  )
})
Share:
12,919
user3006381
Author by

user3006381

Updated on June 19, 2022

Comments

  • user3006381
    user3006381 almost 2 years

    Adding the following template code provided by Materialize doesn't immediately work in a React component:

    <div class="input-field col s12">
      <select>
        <option value="" disabled selected>Choose your option</option>
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
        <option value="3">Option 3</option>
      </select>
      <label>Materialize Select</label>
    </div>
    

    How do fix this so that the select dropdown works?