Getting warning from props passed in MUI styled components related to React not recognizing it

Viewed 1772

I have a styled component that needs to receive props to decide how it should be styled. Looks something like this:

const StyledTypography = styled(Typography)(
  ({ myColor = "black", isLarge = false }) => ({
    "&&": {
      fontSize: isLarge ? 30 : 16,
      border: `1px solid ${myColor}`,
      margin: 10,
      color: myColor
    }
  })
);

Unfortunately isLarge causes the following warning:

Warning: React does not recognize the isLarge prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase islarge instead. If you accidentally passed it from a parent component, remove it from the DOM element.

(Same with myColor)

In another thread, I was told that all that needs to be done is to use shouldForwardProp as a function returning a boolean in the second parameter to decide what props should be passed in tot the DOM DOM:

const StyledTypography = styled(Typography, { shouldForwardProp: () => false })(
 ...
);

Unfortunately this doesn't work.

Is there anyway to do this?

Here is a working sample app with the warnings and everything: https://codesandbox.io/s/crimson-fast-qll47?file=/src/App.js

3 Answers

Try this

import styled from '@emotion/styled'

const StyledTypography = styled(Typography, {
  shouldForwardProp: (prop) => prop !== "myColor" && prop !== "isLarge"
})(
  ...
);

const StyledButton = styled(Button, {
  shouldForwardProp: (prop) => prop !== "myColor"
})(
  ...
);

I have a similar issue with a custom prop on component created with styled from @material-ui/core/styles and it nearly drove me crazy. Using MUI 4.11 the solution with the @emotion/styled did not work for me.

As a solution that worked, I created an intermediate component that doesn't pass the custom props to the DOM.

In the case above, it will look something like

const TypographyComponent = ({myColor, isLarge, ...props}) => <Typography {...props} />;
 
const StyledTypography = styled(TypographyComponent)(
  ({ myColor = "black", isLarge = false }) => ({
    "&&": {
      fontSize: isLarge ? 30 : 16,
      border: `1px solid ${myColor}`,
      margin: 10,
      color: myColor
    }
  })
);

For me this was a viable solution, hope this will help others as well

Customizing prop forwarding in Emotion


use isPropValid from @emotion/is-prop-valid

Example:

import isPropValid from '@emotion/is-prop-valid'
import styled from '@emotion/styled'

const H1 = styled('h1', {
  shouldForwardProp: prop => isPropValid(prop) && prop !== 'color'
})(props => ({
  color: props.color
}))

render(<H1 color="lightgreen">This is lightgreen.</H1>)

NOTE: for Typescript do the following:

const H1 = styled('h1', {
  shouldForwardProp: prop => typeof prop === "string" && isPropValid(prop)
})(props => ({
  color: props.color
}))

check the docs

Related