Search code examples
cssreactjsreact-memo

Why are React defaultProps not passing values?


import { memo } from 'react';
import classNames from 'classnames/bind';
import styles from './Button.module.scss';

const cn = classNames.bind(styles);

const Button = memo(
  ({ design: { size, color, outline, hover }, content, type, onClick }) => (
    <button
      type={type}
      className={cn('button', size, color, { outline }, { hover })}
      onClick={onClick}
    >
      {content}
    </button>
  )
);

Button.defaultProps = {
  size: 'md',
  color: 'black',
};

export default Button;

defaultProps doesn't work in this case. If I set default value when destructuring props like:

{ design: { size='md', color='black', outline, hover }, content, type, onClick }, it works.

I passed the props:

<Button
    design={{ size: 'sm', outline: true }}
    content="Edit"
    onClick={onEditClick}
/>

What's wrong here?


Solution

  • Button.defaultProps = {
      size: 'md',
      color: 'black',
    };
    

    You've defined defaultProps for size and color, but your component doesn't actually use a size or color prop. You do have a design prop, so you could provide a default value for that:

    Button.defaultProps = {
      design: { size: 'md', color: 'black' }
    }
    

    But this will only have an effect if design is undefined. defaultProps will not recurse to nested properties of objects. If you pass an object to design, even an object that doesn't have a color, react will see that the prop is not undefined, and so it won't use the default props.

    If you need to fill in default values for nested object properties, then you will need to write the code for that yourself. For example, the destructuring code you wrote.