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