React项目使用makeStyles时触发读取refs属性的TypeError报错
Cannot read properties of undefined (reading 'refs') 排查方案 这个报错是MUI v4从服务端协同渲染迁移到独立React应用时的高频问题,核心原因是makeStyles的样式管理上下文丢失,按以下优先级排查即可:
优先排查多依赖实例问题(90%的迁移场景踩这个坑)
makeStyles依赖全局统一的样式实例上下文维护组件和样式的引用关系,如果项目里存在多份React、多份@material-ui/styles/@material-ui/core实例,上下文不互通,组件卸载时就会拿不到样式引用报这个错。
先在项目根目录执行以下命令检查重复依赖:npm ls react npm ls react-dom npm ls @material-ui/styles npm ls @material-ui/core如果输出结果中存在多版本嵌套依赖(比如某个依赖自己带了一份node_modules里的react,或者@material-ui/styles版本不一致),直接在构建配置里加别名强制全项目引用根目录的依赖即可:
Vite配置示例import path from 'path' import { defineConfig } from 'vite' export default defineConfig({ resolve: { alias: { 'react': path.resolve(__dirname, './node_modules/react'), 'react-dom': path.resolve(__dirname, './node_modules/react-dom'), '@material-ui/styles': path.resolve(__dirname, './node_modules/@material-ui/styles'), '@material-ui/core': path.resolve(__dirname, './node_modules/@material-ui/core') } } })Webpack配置示例
const path = require('path') module.exports = { resolve: { alias: { 'react': path.resolve(__dirname, 'node_modules/react'), 'react-dom': path.resolve(__dirname, 'node_modules/react-dom'), '@material-ui/styles': path.resolve(__dirname, 'node_modules/@material-ui/styles'), '@material-ui/core': path.resolve(__dirname, 'node_modules/@material-ui/core') } } }检查根组件的StylesProvider包裹是否正确
MUI v4的makeStyles需要StylesProvider在应用最外层提供上下文,如果独立应用搭建时忘了包裹,或者包裹位置放在了路由/条件渲染内部,组件卸载时上下文销毁就会触发报错。
入口文件的正确写法参考:import React from 'react' import ReactDOM from 'react-dom/client' import { StylesProvider } from '@material-ui/core/styles' import App from './App' ReactDOM.createRoot(document.getElementById('root')).render( <StylesProvider injectFirst> <App /> </StylesProvider> )检查React与ReactDOM版本对齐情况
如果react和react-dom版本不一致(比如装了React 18但react-dom停留在17版本),hook的生命周期执行逻辑会出现偏差,导致makeStyles的useEffect清理函数执行时拿不到预期的状态引用。重新安装对齐两个依赖的版本即可。排查旧react-rails的全局残留冲突
迁移时如果Rails模板页还保留了旧的react-rails时代全局注入的MUI脚本、样式上下文,页面会同时存在两套MUI样式管理逻辑,卸载组件时会误操作已销毁的实例。把Rails模板中旧的React、MUI相关全局引入全部移除,保证页面只有独立应用加载的一份MUI runtime即可。
排查修改完成后,建议删除node_modules和对应的锁文件(package-lock.json/yarn.lock/pnpm-lock.yaml),重新执行依赖安装命令后重启开发服务,避免缓存导致问题复现。
内容的提问来源于stack exchange,提问作者Gotey

