Material-ui从v3升级到v4后出现主题上下文及ThemeProvider相关错误求助
Hey there, let's break down and fix these two errors you're seeing after upgrading from Material-UI v3 to v4. Both issues boil down to how your app is handling theme and JSS context, so let's tackle them step by step:
Root Cause Analysis
- Missing
__THEMING__Context: The error means components likeStatelessNotificationProvider(either your own or a dependency) need access to Material-UI's theme context, but it's not being provided because your root app isn't wrapped in yourUIProvider(which containsThemeProvider). - ThemeProvider Required Error: Even if you're not using
WithThemedirectly, many Material-UI internal components (and third-party components built on it) rely on the theme context under the hood. WithoutThemeProvider, they'll throw this error.
Step-by-Step Fixes
1. Wrap Your Root App in UIProvider
Looking at your App.tsx, you're rendering <App /> directly inside BrowserRouter but not wrapping it in your UIProvider. That means the ThemeProvider and JssProvider in UIProvider aren't being applied to your app's components.
Update your App.tsx to include the UIProvider:
// Make sure to import UIProvider from your Index.tsx file import { UIProvider } from './Index'; ReactDOM.render( <BrowserRouter> <UIProvider> <App /> </UIProvider> </BrowserRouter>, document.getElementById('root') as HTMLElement );
2. Replace JssProvider with StylesProvider (Material-UI v4 Recommendation)
Material-UI v4 moved JSS-related utilities to the @material-ui/styles package, and JssProvider has been replaced with StylesProvider for better compatibility. This will resolve potential context conflicts between your custom JSS setup and Material-UI's internal handling.
First, install the package if you haven't:
npm install @material-ui/styles # or yarn add @material-ui/styles
Then update your Index.tsx code:
// Replace JssProvider with StylesProvider, and import from @material-ui/styles import { StylesProvider, createGenerateClassName } from '@material-ui/styles'; import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles'; // ... keep your existing createSATheme, ProviderProps, etc. const UIProvider = ({ children, theme }: ProviderProps) => { let classNameReferenceCount = 0; const generateClassName = isTest ? (rule, styleSheet) => `test-${styleSheet.options.classNamePrefix}-${rule.key}-${classNameReferenceCount++}` : createGenerateClassName({ productionPrefix: `c${providerReferenceCount++}-` }); return ( <StylesProvider generateClassName={generateClassName}> <ThemeProvider theme={theme || createSATheme()}> {children} </ThemeProvider> </StylesProvider> ); };
3. Fix Global Styles (Avoid Manual JSS StyleSheet Attachment)
Your current code manually creates and attaches a JSS style sheet for global styles. In v4, Material-UI provides a GlobalStyles component that integrates seamlessly with the theme system, which is more reliable than manual JSS operations.
Update your global styles implementation:
import { GlobalStyles } from '@material-ui/core'; // Inside UIProvider, add the GlobalStyles component const UIProvider = ({ children, theme }: ProviderProps) => { // ... existing generateClassName logic return ( <StylesProvider generateClassName={generateClassName}> <ThemeProvider theme={theme || createSATheme()}> <GlobalStyles styles={{ '@global': { ...globalStyles } }} /> {children} </ThemeProvider> </StylesProvider> ); }; // Remove the manual jss.createStyleSheet().attach() code
Why This Works
- Wrapping your app in
UIProviderensures every component in your tree has access to the theme context provided byThemeProvider. - Using
StylesProvideraligns your JSS setup with Material-UI v4's internal standards, eliminating context conflicts that caused the__THEMING__undefined error. - The
GlobalStylescomponent integrates global styles into the Material-UI theme system, avoiding issues with manual JSS style sheet management.
内容的提问来源于stack exchange,提问作者Pranav

