React中初始化Materializecss Select报错:$(...).material_select不是函数
$(...).material_select is not a function & Dynamic Select Issues in React + Materialize CSS Hey there! Let's break down what's going on here and how to fix both problems—the missing function error and the inconsistent option display in your dynamic Materialize select fields.
First: Why the material_select function is missing
This error usually pops up for one of a few common reasons:
- Materialize's JavaScript isn't loaded correctly, or it's loaded before jQuery (which it depends on)
- You're calling the method before the DOM (or Materialize itself) is fully ready in your React component
- If you're using modular imports, you haven't properly set up Materialize's JS in your project
1. Get your dependencies & load order right
First, make sure you have jQuery and Materialize installed and imported correctly:
- If using npm/yarn, install them first:
npm install jquery materialize-css
Then in your project's entry file (like index.js), import them in this exact order:
import $ from 'jquery'; import 'materialize-css/dist/css/materialize.min.css'; import 'materialize-css/dist/js/materialize.min.js'; // Make jQuery available globally (optional but avoids headaches) window.$ = $; window.jQuery = $;
If you're using CDNs, load them in this order too: jQuery → Materialize CSS → Materialize JS.
2. Call material_select() at the right time in React
React's component lifecycle means you can't just call DOM methods whenever—you need to wait until the component (and your dynamic options) are rendered. Here's how to do it for both function and class components:
Function Component Example
import { useEffect, useState, useRef } from 'react'; function DynamicSelect() { const [options, setOptions] = useState([]); const selectRef = useRef(null); // Use a ref to target the select element // Simulate fetching dynamic options (replace with your actual data source) useEffect(() => { setTimeout(() => { setOptions([ { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' } ]); }, 1000); }, []); // Initialize Materialize select AFTER options are rendered useEffect(() => { if (options.length > 0 && selectRef.current) { // First destroy any existing instance to avoid conflicts $(selectRef.current).material_select('destroy'); // Re-initialize the select $(selectRef.current).material_select(); // Cleanup: destroy the instance when component unmounts or options change return () => { $(selectRef.current).material_select('destroy'); }; } }, [options]); // Re-run this effect when options update return ( <div className="input-field"> <select ref={selectRef}> <option value="" disabled selected>Choose your option</option> {options.map(opt => ( <option key={opt.value} value={opt.value}>{opt.label}</option> ))} </select> <label>Dynamic Select</label> </div> ); } export default DynamicSelect;
Class Component Example
import React, { Component } from 'react'; class DynamicSelect extends Component { state = { options: [] }; selectRef = React.createRef(); componentDidMount() { // Simulate fetching options setTimeout(() => { this.setState({ options: [ { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' } ] }); }, 1000); } componentDidUpdate(prevProps, prevState) { // Only re-initialize if options changed if (prevState.options.length !== this.state.options.length && this.selectRef.current) { $(this.selectRef.current).material_select('destroy'); $(this.selectRef.current).material_select(); } } componentWillUnmount() { // Cleanup to prevent memory leaks if (this.selectRef.current) { $(this.selectRef.current).material_select('destroy'); } } render() { return ( <div className="input-field"> <select ref={this.selectRef}> <option value="" disabled selected>Choose your option</option> {this.state.options.map(opt => ( <option key={opt.value} value={opt.value}>{opt.label}</option> ))} </select> <label>Dynamic Select</label> </div> ); } } export default DynamicSelect;
Why your options are showing inconsistently?
The unstable display almost always comes down to timing:
- You were calling
material_select()before your dynamic options finished rendering to the DOM - If you don't destroy old Materialize select instances before re-initializing, it causes conflicts that hide options
- Forgetting unique
keyprops on your<option>elements can make React fail to update the DOM correctly when options change
Quick Bonus Tip
If you're using Materialize v1.0.0 or newer, the method was renamed from material_select() to formSelect()! So update your code to use $(element).formSelect() instead if you're on the latest version.
内容的提问来源于stack exchange,提问作者Jay_l

