如何用styled-components正确覆盖ExpansionPanelSummary深层元素?
I’ve run into this exact issue before—let me break down what’s happening and how to fix it.
The core problem here is how Material UI’s ExpansionPanel identifies its child components. Under the hood, ExpansionPanel looks for specific component types (or their muiName property) to determine where to place the ExpansionPanelSummary vs. the collapsible content. When you wrap MUIExpansionPanelSummary in an anonymous function component inside styled(), you’re creating a new, unrecognized component type. MUI can’t tell this is supposed to be the summary, so it treats it like regular content and drops it inside the Collapse container—hence the shifted DOM structure you’re seeing.
Solution 1: Directly Style the MUI Component (Simplest Approach)
Instead of wrapping the component in a function first, pass the raw MUIExpansionPanelSummary directly to styled(). You can still override root and deep elements using the same && specificity trick:
import MUIExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary'; export const ExpansionPanelSummary = styled(MUIExpansionPanelSummary)` && { // Root styles go here (e.g., background-color, padding) } && .MuiExpansionPanelSummary-content { // Styles for deep elements like the content wrapper } &&.Mui-expanded { // Styles for the expanded state } `;
Solution 2: Preserve MUI Component Identification (If You Need Custom Props/Classes)
If you need to pass custom classes or modify props before styling (like you did with ExpansionPanel), you just need to tell MUI what your custom component is by setting the muiName property:
import MUIExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary'; // First define your custom component with props/classes const CustomSummary = (props) => ( <MUIExpansionPanelSummary classes={{ expanded: 'expanded' }} {...props} /> ); // Critical: Set muiName so MUI recognizes this as an ExpansionPanelSummary CustomSummary.muiName = 'ExpansionPanelSummary'; // Now style it normally export const ExpansionPanelSummary = styled(CustomSummary)` && { // Root styles } &&.expanded { // Expanded state styles } `;
This works because ExpansionPanel checks for the muiName property when identifying child components. By setting it to match the original MUI component’s name, you restore the correct DOM structure and behavior.
After implementing either solution, your DOM should go back to the expected structure:
<div class="MuiExpansionPanel..."> <div class="MuiExpansionPanelSummary..." /> <div class="MuiCollapse-container..."> <div class="MuiCollapse-wrapper..."> <div class="MuiCollapse-wrapperInner..."> <div class="MuiExpansionPanelDetails..." /> </div> </div> </div> </div>
内容的提问来源于stack exchange,提问作者ericsoco

