Skip to content

Commit

Permalink
fix(AutoControlledComponent): fix behaviour when undefined it passed (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
layershifter authored Nov 25, 2018
1 parent defd978 commit fca4035
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 127 deletions.
58 changes: 33 additions & 25 deletions src/lib/AutoControlledComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,15 @@ export default class AutoControlledComponent extends Component {
const defaultProp = getDefaultPropName(prop)
// regular prop
if (!_.has(propTypes, defaultProp)) {
console.error(`${name} is missing "${defaultProp}" propTypes validation for auto controlled prop "${prop}".`)
console.error(
`${name} is missing "${defaultProp}" propTypes validation for auto controlled prop "${prop}".`,
)
}
// its default prop
if (!_.has(propTypes, prop)) {
console.error(`${name} is missing propTypes validation for auto controlled prop "${prop}".`)
console.error(
`${name} is missing propTypes validation for auto controlled prop "${prop}".`,
)
}
})

Expand All @@ -106,25 +110,31 @@ export default class AutoControlledComponent extends Component {
// https://babeljs.io/blog/2015/06/07/react-on-es6-plus#property-initializers
const illegalDefaults = _.intersection(autoControlledProps, _.keys(defaultProps))
if (!_.isEmpty(illegalDefaults)) {
console.error([
'Do not set defaultProps for autoControlledProps. You can set defaults by',
'setting state in the constructor or using an ES7 property initializer',
'(https://babeljs.io/blog/2015/06/07/react-on-es6-plus#property-initializers)',
`See ${name} props: "${illegalDefaults}".`,
].join(' '))
console.error(
[
'Do not set defaultProps for autoControlledProps. You can set defaults by',
'setting state in the constructor or using an ES7 property initializer',
'(https://babeljs.io/blog/2015/06/07/react-on-es6-plus#property-initializers)',
`See ${name} props: "${illegalDefaults}".`,
].join(' '),
)
}

// prevent listing defaultProps in autoControlledProps
//
// Default props are automatically handled.
// Listing defaults in autoControlledProps would result in allowing defaultDefaultValue props.
const illegalAutoControlled = _.filter(autoControlledProps, prop => _.startsWith(prop, 'default'))
const illegalAutoControlled = _.filter(autoControlledProps, prop =>
_.startsWith(prop, 'default'),
)
if (!_.isEmpty(illegalAutoControlled)) {
console.error([
'Do not add default props to autoControlledProps.',
'Default props are automatically handled.',
`See ${name} autoControlledProps: "${illegalAutoControlled}".`,
].join(' '))
console.error(
[
'Do not add default props to autoControlledProps.',
'Default props are automatically handled.',
`See ${name} autoControlledProps: "${illegalAutoControlled}".`,
].join(' '),
)
}
}

Expand Down Expand Up @@ -157,14 +167,10 @@ export default class AutoControlledComponent extends Component {

// Solve the next state for autoControlledProps
const newState = autoControlledProps.reduce((acc, prop) => {
const isNextUndefined = _.isUndefined(nextProps[prop])
const propWasRemoved = !_.isUndefined(this.props[prop]) && isNextUndefined
const isNextDefined = !_.isUndefined(nextProps[prop])

// if next is defined then use its value
if (!isNextUndefined) acc[prop] = nextProps[prop]

// reinitialize state for props just removed / set undefined
else if (propWasRemoved) acc[prop] = getAutoControlledStateValue(prop, nextProps)
if (isNextDefined) acc[prop] = nextProps[prop]

return acc
}, {})
Expand All @@ -185,11 +191,13 @@ export default class AutoControlledComponent extends Component {
// warn about failed attempts to setState for keys not listed in autoControlledProps
const illegalKeys = _.difference(_.keys(maybeState), autoControlledProps)
if (!_.isEmpty(illegalKeys)) {
console.error([
`${name} called trySetState() with controlled props: "${illegalKeys}".`,
'State will not be set.',
'Only props in static autoControlledProps will be set on state.',
].join(' '))
console.error(
[
`${name} called trySetState() with controlled props: "${illegalKeys}".`,
'State will not be set.',
'Only props in static autoControlledProps will be set on state.',
].join(' '),
)
}
}

Expand Down
Loading

0 comments on commit fca4035

Please sign in to comment.