简体   繁体   中英

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

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?

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>

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

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

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.

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.

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>
  )
})

If you dont want to use 'react-dom' library I asume you are using 'materialize-css' library instead as it say in the materializecss webpage. For that you have to do this in your Component:

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

export default class Navbar extends Component{
    componentDidMount(){
        console.log(M);
        M.AutoInit();
    }
    render(){
        return (
              <div>
               <div className="input-field col s12">
                <select defaultValue="">
                  <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>
              </div>
            )
    }
}

First install materialize-css via npm or yarn. Then follow the code below.

import React, { useEffect } from "react";
import M from "materialize-css";
const Orders = (props) => {
  useEffect(() => {
    // imitialize dropdown
    var elems = document.getElementById("sel");
    var instances = window.M.FormSelect.init(elems, {});
  }, []);

  return (
    <div class="input-field col s12">
      <select  id="sel">
        <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>
  );
};

export default Orders;

First, make sure you import materialize-css

import M from 'materialize-css';  

Then, inside of the page function (export default function.....() ), do the following:

useEffect (()=>{
        M.AutoInit();
    }, [])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM