You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS集成Materialize时Select组件仅刷新后渲染问题排查

解决React + Materialize Select组件路由跳转后不渲染的问题

嘿,这个坑我之前踩过!核心原因就是Materialize的Select组件得在DOM加载完成后手动初始化,而React单页应用路由跳转时,整个页面不会刷新,document.ready里的初始化代码只会在首次加载首页时跑一次,后续跳转页面里的Select自然就没被初始化,所以看不到效果。

给你几个落地的解决方案:

1. 在React组件内手动初始化Select

不管是函数组件还是类组件,都可以在组件挂载/更新完成时,手动调用Materialize的Select初始化方法:

函数组件(用useEffect)

import { useEffect, useRef } from 'react';

function CustomSelect() {
  const selectRef = useRef(null);

  useEffect(() => {
    // 确保DOM元素已经挂载
    if (selectRef.current) {
      // 初始化Materialize Select
      M.FormSelect.init(selectRef.current);
    }

    // 组件卸载时清理实例,避免内存泄漏
    return () => {
      const instance = M.FormSelect.getInstance(selectRef.current);
      if (instance) instance.destroy();
    };
  }, []); // 如果选项是动态生成的,把选项数组加到依赖里

  return (
    <div className="input-field">
      <select ref={selectRef}>
        <option value="" disabled selected>选择选项</option>
        <option value="1">选项1</option>
        <option value="2">选项2</option>
      </select>
      <label>Materialize Select</label>
    </div>
  );
}

类组件

class CustomSelect extends React.Component {
  constructor(props) {
    super(props);
    this.selectRef = React.createRef();
  }

  componentDidMount() {
    if (this.selectRef.current) {
      M.FormSelect.init(this.selectRef.current);
    }
  }

  componentDidUpdate(prevProps) {
    // 如果选项是从props传入的动态数据,变化后重新初始化
    if (prevProps.options !== this.props.options) {
      const instance = M.FormSelect.getInstance(this.selectRef.current);
      if (instance) instance.destroy();
      M.FormSelect.init(this.selectRef.current);
    }
  }

  componentWillUnmount() {
    const instance = M.FormSelect.getInstance(this.selectRef.current);
    if (instance) instance.destroy();
  }

  render() {
    return (
      <div className="input-field">
        <select ref={this.selectRef}>
          <option value="" disabled selected>选择选项</option>
          {this.props.options.map(opt => (
            <option key={opt.value} value={opt.value}>{opt.label}</option>
          ))}
        </select>
        <label>Materialize Select</label>
      </div>
    );
  }
}

2. 别再依赖全局的document.ready

你在index.html里写的DOMContentLoaded初始化代码,只能覆盖首次加载的页面元素。路由跳转后新增的DOM元素,必须在组件层面单独处理初始化,才能保证每个页面的Select都能正常渲染。

比如你的index.html里可能有这段代码:

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var elems = document.querySelectorAll('select');
    var instances = M.FormSelect.init(elems);
  });
</script>

它只会在页面首次加载时执行,路由跳转后新生成的select不会被选中初始化,所以必须在组件内单独处理。

3. 动态选项的额外注意点

如果你的Select选项是异步加载的(比如从API获取),一定要等数据加载完成后再执行初始化。这时候要把选项数组加到useEffect的依赖数组(函数组件),或者在componentDidUpdate里对比props变化(类组件),确保数据更新后重新初始化Select。

这样处理后,不管是路由跳转还是动态更新选项,Select组件都能正常显示啦!

内容的提问来源于stack exchange,提问作者Lennert Hofman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:50:56