Customizing React components with Material UI v5 using 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 PrimaryBadge = styled(Badge)``

// Setting default prop: max to Infinity for PrimaryBadge
PrimaryBadge.defaultProps = {
    max: Infinity
}


const SecondaryBadge = styled(PrimaryBadge)``    // Styling PrimaryBadge

// Overriding defaultProps from PrimaryBadge. Prop max: Infinity does not apply here
SecondaryBadge.defaultProps = {
    variant: 'standard'
}

SecondaryBadge now has only variant: 'standard' as the default prop, skipping max: Infinity

Is there a way to preserve all defaultProps from each styling level?

Answer №1

When utilizing multiple styled calls in Emotion to style a component, Emotion consolidates the styling layers into one wrapper component instead of adding an extra wrapper around the initial one. The previous defaultProps are retained by Emotion, but get overridden when you define Badge2.defaultProps.

To preserve any existing defaultProps, use the following syntax:

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

The example below illustrates default props behavior with each successive styled wrapping. The solution is exemplified 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>
  );
}

https://codesandbox.io/s/styled-and-defaultprops-dk26u0?fontsize=14&hidenavigation=1&theme=dark

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with Stack Divider not appearing on Chakra UI card

I'm currently designing a card element using Chakra UI. However, I've noticed that the Stack Divider in the Card Body isn't displaying as expected. Is there a specific way it needs to be structured for it to show up? For example, should I se ...

Is there a way to implement the scroll into view feature from one page to another using React and Redux?

Being relatively new to frontend development, I recently started my first job in this field. My current project involves working on a website built with React and Redux. The challenge I am facing is related to a page that consists of multiple sections of d ...

Having trouble with React Page crashing when trying to access the component state

I'm attempting to create a side-bar menu that swaps out content in a <main> tag when menu buttons are clicked. However, I'm facing an issue where the page becomes unresponsive and eventually crashes due to React issues while trying to read ...

Utilize Docker on AWS for seamless deployment and execution

After completing my React and NodeJS projects, I created a Dockerfile for each one and then a docker-compose file to generate docker images for both the frontend and backend. I have also uploaded the images to my repository on Docker hub. Now, I want to r ...

Capture the moment a button is clicked, save it in the database, and showcase it on the page using React

This might be a challenging question, but I'm up for the challenge! I'm currently working on a website using the MERN stack, and I'd like to implement a feature where users can click a button that says "check-in", which would then store the ...

Utilizing an arrow function enclosed within curly brackets to manage React context

During a React context tutorial, I came across this code snippet: <MyContext.Consumer> {value => /* render something based on the context value */} </MyContext.Consumer> This part, value => /* render something based on the context valu ...

Using Material-UI's <Autocomplete/> component and the getOptionLabel prop to handle an empty string value

Currently, I am working with material-ui autocomplete and passing an array of states to its options property. However, I have encountered an issue with the getOptionLabel method: Material-UI: The `getOptionLabel` method of Autocomplete returned undefined ...

What is the correct approach to hiding problems in Flow NPM packages to ensure that end-user applications do not encounter any errors?

When utilizing something like $FlowIssue, it cannot be ensured that it will be included in every .flowconfig file. Defining a library interface appears to only function within the specific project and not in other projects that import the package (even if ...

What is the alternative method for importing the browser module in next.js without using dynamic imports?

const MonacoHighlighter = require("monaco-jsx-highlighter"); After encountering a "document not found" error with this import in next.js, I attempted to find an alternative solution. const Highlighter = new MonacoHighlighter(); By directly instantiating ...

Encountering a Basic React Issue: Unable to Implement @material-ui/picker in Next.js

I'm currently attempting to integrate the @material-ui/pickers library into my Next.js application. In order to incorporate the Picker provider, I followed the guidance provided in the Next.js documentation by adding the _app.js file inside /pages: i ...

What is the easiest way to compile a single .ts file in my src folder? I can achieve this by configuring the tsconfig.js file and running the yarn

{ "compilerOptions": { "target": "es5", "lib": [ "dom", "dom.iterable", "esnext" ], "allowJs": true, "skipLibCheck": true, ...

What is the best way to increase the row spacing in an Ant Design Table?

I have a table with expandable rows in antd, and I am looking to add some vertical space between the rows. I've tried using the rowClassName property provided by antd, but it did not work as expected. I also attempted to use a custom component, but th ...

Encountering a problem while trying to choose an autofill value in the input number component of Prime

I'm encountering an issue while attempting to select an autofill value. Currently, I am utilizing the PrimeReact InputNumber component. View image here Upon debugging, I noticed that there is no value in the event. Even after disabling autocomplete ...

Is it possible to incorporate a click function into the Material UI Box component?

Currently, I have successfully implemented displaying data in a loop with boxes. However, I need to disable and enable functionality based on certain conditions, similar to a button within the box. On enabling, I should be able to implement a click functio ...

Utilizing a function within a map function for a nested attribute of a map

I have created a Spring Boot backend endpoint that accepts a customer ID and returns the total number of orders made by that customer. The endpoint is structured using PathVariable in Spring Boot, so the URL looks like this: "api/v1/totalorders/{id} ...

Using TypeScript, effortlessly retrieve objects within React components based on their keys

I am looking for a way to dynamically choose a React component based on a key within an object import React, {useState, useEffect} from 'react' import ComponentA from '@components/ComponentA'; import ComponentB from '@components/Co ...

Whenever a new entry is made into the textfield, the onChange feature triggers a reset on the content within the textfield

I'm experiencing an issue while creating a SignUp authentication page with Firebase. Every time I try to input text in the text field, it gets reset automatically. I have been unable to identify the root cause of this problem. It seems to be related t ...

Display a notification depending on the condition met

I have multiple backend conditions that I need to check in order to display an alert within an antd modal. The initial code looks like this: Modal.confirm({ centered: true, title: 'Sorry, you cannot create Menu without satisfying the following ...

Encountered an error trying to access the length property of an undefined variable while passing props

I need help with my shopping app project. I am trying to create a feature where if the cart is empty, it should display a message saying "shopping cart is empty." However, when I try to implement this, I keep getting a type error that says "Cannot read p ...

Challenge Encountered with Create-React-App TypeScript Template: Generating JS Files Instead of TSX Files

Encountering a problem setting up a new React application with TypeScript using the Create-React-App template. Followed the guidelines on the official documentation (https://create-react-app.dev/docs/adding-typescript/) and ran the command below: npx creat ...