Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Material UI v5 styled with defaultProps

When using multiple styled components, the top one overrides other default props.

import { styled } from '@mui/material/styles'
import { Badge } from '@mui/material'


const Badge1 = styled(Badge)``

// this works if Badge1 is used directly: <Badge1 />
Badge1.defaultProps = {
    max: Infinity
}


const Badge2 = styled(Badge1)``    // styled Badge1

// this overrides defaultProps from Badge1. Prop max: Infinity does no apply here
Badge2.defaultProps = {
    variant: 'standard'
}

Badge2 has only variant: 'standard' default prop. It skips max: Infinity

How can I keep all the defaultProps from each level

like image 206
Oki Avatar asked Oct 14 '25 20:10

Oki


1 Answers

When you style a component via multiple styled calls using Emotion, Emotion collapses the styling layers into a single wrapper component rather than adding an additional wrapper around the first wrapper. Emotion retains the defaultProps from the previous wrapper, but you are then overwriting that when you set Badge2.defaultProps.

You can retain any previous defaultProps with the following syntax:

Badge2.defaultProps = {
    ...Badge2.defaultProps,
    variant: 'standard'
}

Below is an example demonstrating what happens with default props with each styled wrapping. The fix is demonstrated with StyledAgainWithDefaultRetainExisting.

import styled from "@emotion/styled";

function MyComponent({ className, ...defaults }) {
  return <div className={className}>Defaults: {JSON.stringify(defaults)}</div>;
}
MyComponent.defaultProps = {
  orig: true
};

const StyledMyComponent = styled(MyComponent)`
  background-color: blue;
  color: white;
`;
StyledMyComponent.defaultProps = {
  styled: true
};

const StyledAgainNoDefaultsAdded = styled(StyledMyComponent)`
  background-color: purple;
`;

const StyledAgainWithDefault = styled(StyledMyComponent)`
  background-color: green;
`;
StyledAgainWithDefault.defaultProps = {
  styledAgain: true
};

const StyledAgainWithDefaultRetainExisting = styled(StyledMyComponent)`
  background-color: brown;
`;
StyledAgainWithDefaultRetainExisting.defaultProps = {
  ...StyledAgainWithDefaultRetainExisting.defaultProps,
  styledAgainRetain: true
};

export default function App() {
  return (
    <div>
      <MyComponent />
      <StyledMyComponent />
      <StyledAgainNoDefaultsAdded />
      <StyledAgainWithDefault />
      <StyledAgainWithDefaultRetainExisting />
    </div>
  );
}

Edit styled and defaultProps

like image 134
Ryan Cogswell Avatar answered Oct 17 '25 08:10

Ryan Cogswell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!