Skip to content

Latest commit

 

History

History
277 lines (218 loc) · 5.35 KB

require-default-props.md

File metadata and controls

277 lines (218 loc) · 5.35 KB

Enforce a defaultProps definition for every prop that is not a required prop (react/require-default-props)

This rule aims to ensure that any non-required PropType declaration of a component has a corresponding defaultProps value.

One advantage of defaultProps over custom default logic in your code is that defaultProps are resolved by React before the PropTypes typechecking happens, so typechecking will also apply to your defaultProps. The same also holds true for stateless functional components: default function parameters do not behave the same as defaultProps and thus using defaultProps is still preferred.

To illustrate, consider the following example:

With defaultProps:

const HelloWorld = ({ name }) => (
  <h1>Hello, {name.first} {name.last}!</h1>
);

HelloWorld.propTypes = {
  name: PropTypes.shape({
    first: PropTypes.string,
    last: PropTypes.string,
  })
};

HelloWorld.defaultProps = {
  name: 'john'
};

// Logs:
// Invalid prop `name` of type `string` supplied to `HelloWorld`, expected `object`.
ReactDOM.render(<HelloWorld />,  document.getElementById('app'));

Without defaultProps:

const HelloWorld = ({ name = 'John Doe' }) => (
  <h1>Hello, {name.first} {name.last}!</h1>
);

HelloWorld.propTypes = {
  name: PropTypes.shape({
    first: PropTypes.string,
    last: PropTypes.string,
  })
};

// Nothing is logged, renders:
// "Hello,!"
ReactDOM.render(<HelloWorld />,  document.getElementById('app'));

Rule Details

The following patterns are considered warnings:

function MyStatelessComponent({ foo, bar }) {
  return <div>{foo}{bar}</div>;
}

MyStatelessComponent.propTypes = {
  foo: PropTypes.string.isRequired,
  bar: PropTypes.string
};
var Greeting = createReactClass({
  render: function() {
    return <div>Hello {this.props.foo} {this.props.bar}</div>;
  },

  propTypes: {
    foo: PropTypes.string,
    bar: PropTypes.string
  },

  getDefaultProps: function() {
    return {
      foo: "foo"
    };
  }
});
class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.foo} {this.props.bar}</h1>
    );
  }
}

Greeting.propTypes = {
  foo: PropTypes.string,
  bar: PropTypes.string
};

Greeting.defaultProps = {
  foo: "foo"
};
type Props = {
  foo: string,
  bar?: string
};

function MyStatelessComponent(props: Props) {
  return <div>Hello {props.foo} {props.bar}</div>;
}

The following patterns are not considered warnings:

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.foo} {this.props.bar}</h1>
    );
  }

  static propTypes = {
    foo: PropTypes.string,
    bar: PropTypes.string.isRequired
  };

  static defaultProps = {
    foo: "foo"
  };
}
function MyStatelessComponent({ foo, bar }) {
  return <div>{foo}{bar}</div>;
}

MyStatelessComponent.propTypes = {
  foo: PropTypes.string.isRequired,
  bar: PropTypes.string.isRequired
};
function MyStatelessComponent({ foo, bar }) {
  return <div>{foo}{bar}</div>;
}

MyStatelessComponent.propTypes = {
  foo: PropTypes.string.isRequired,
  bar: PropTypes.string
};

MyStatelessComponent.defaultProps = {
    bar: 'some default'
};
type Props = {
  foo: string,
  bar?: string
};

function MyStatelessComponent(props: Props) {
  return <div>Hello {props.foo} {props.bar}</div>;
}

MyStatelessComponent.defaultProps = {
  bar: 'some default'
};
function NotAComponent({ foo, bar }) {}

NotAComponent.propTypes = {
  foo: PropTypes.string,
  bar: PropTypes.string.isRequired
};

Rule Options

...
"react/require-default-props": [<enabled>, { forbidDefaultForRequired: <boolean> }]
...
  • enabled: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.
  • forbidDefaultForRequired: optional boolean to forbid prop default for a required prop. Defaults to false.

forbidDefaultForRequired

Forbids setting a default for props that are marked as isRequired.

The following patterns are warnings:

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.foo} {this.props.bar}</h1>
    );
  }

  static propTypes = {
    foo: PropTypes.string,
    bar: PropTypes.string.isRequired
  };

  static defaultProps = {
    foo: "foo",
    bar: "bar"
  };
}
function MyStatelessComponent({ foo, bar }) {
  return <div>{foo}{bar}</div>;
}

MyStatelessComponent.propTypes = {
  foo: PropTypes.string.isRequired,
  bar: PropTypes.string
};

MyStatelessComponent.defaultProps = {
  foo: 'foo',
  bar: 'bar'
};

The following patterns are not warnings:

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.foo} {this.props.bar}</h1>
    );
  }

  static propTypes = {
    foo: PropTypes.string,
    bar: PropTypes.string.isRequired
  };

  static defaultProps = {
    foo: "foo"
  };
}
function MyStatelessComponent({ foo, bar }) {
  return <div>{foo}{bar}</div>;
}

MyStatelessComponent.propTypes = {
  foo: PropTypes.string.isRequired,
  bar: PropTypes.string.isRequired
};

When Not To Use It

If you don't care about using defaultsProps for your component's props that are not required, you can disable this rule.

Resources