Skip to content

Commit a7f3fed

Browse files
committed
breaking(AutoControlledProps): Ignore undefined
1 parent 33073ca commit a7f3fed

File tree

2 files changed

+97
-5
lines changed

2 files changed

+97
-5
lines changed

src/lib/AutoControlledComponent.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,13 @@ export default class AutoControlledComponent extends Component {
121121
componentWillReceiveProps(nextProps) {
122122
if (super.componentWillReceiveProps) super.componentWillReceiveProps(nextProps)
123123

124-
// props always win, update state with all auto controlled prop
125-
const newState = _.pick(nextProps, this.constructor.autoControlledProps)
124+
// Props always win, update state with all auto controlled prop that were
125+
// defined by the parent.
126+
const newState = _.pick(
127+
_.omitBy(nextProps, _.isUndefined),
128+
this.constructor.autoControlledProps
129+
)
130+
126131
if (!_.isEmpty(newState)) this.setState(newState)
127132
}
128133

@@ -147,9 +152,10 @@ export default class AutoControlledComponent extends Component {
147152
}
148153
}
149154

150-
// pick auto controlled props
151-
// omit props from parent
152-
let newState = _.omit(_.pick(maybeState, autoControlledProps), _.keys(this.props))
155+
const parentDefinedProps = _.omitBy(this.props, _.isUndefined)
156+
157+
// Pick auto controlled props, omitting props defined by the parent.
158+
let newState = _.omit(_.pick(maybeState, autoControlledProps), _.keys(parentDefinedProps))
153159

154160
if (state) newState = { ...newState, ...state }
155161

test/specs/lib/AutoControlledComponent-test.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,56 @@ describe('extending AutoControlledComponent', () => {
9595
wrapper
9696
.should.have.state(randomProp, props[randomProp])
9797
})
98+
99+
it('sets state for props passed as undefined by the parent', () => {
100+
consoleUtil.disableOnce()
101+
102+
const props = makeProps()
103+
const autoControlledProps = _.keys(props)
104+
105+
const randomProp = _.sample(autoControlledProps)
106+
const randomValue = faker.hacker.phrase()
107+
108+
props[randomProp] = undefined
109+
110+
TestClass = createTestClass({ autoControlledProps, state: {} })
111+
const wrapper = shallow(<TestClass {...props } />)
112+
113+
wrapper
114+
.instance()
115+
.trySetState({ [randomProp]: randomValue })
116+
117+
// not updated
118+
wrapper
119+
.should.have.state(randomProp, randomValue)
120+
})
121+
122+
it('does not set state for props passed as null by the parent', () => {
123+
consoleUtil.disableOnce()
124+
125+
const props = makeProps()
126+
const autoControlledProps = _.keys(props)
127+
128+
const randomProp = _.sample(autoControlledProps)
129+
const randomValue = faker.hacker.phrase()
130+
131+
props[randomProp] = null
132+
133+
TestClass = createTestClass({ autoControlledProps, state: {} })
134+
const wrapper = shallow(<TestClass {...props } />)
135+
136+
wrapper
137+
.instance()
138+
.trySetState({ [randomProp]: randomValue })
139+
140+
// not updated
141+
wrapper
142+
.should.not.have.state(randomProp, randomValue)
143+
144+
// is original value
145+
wrapper
146+
.should.have.state(randomProp, props[randomProp])
147+
})
98148
})
99149

100150
describe('initial state', () => {
@@ -244,5 +294,41 @@ describe('extending AutoControlledComponent', () => {
244294
wrapper
245295
.should.not.have.state(randomDefaultProp, randomValue)
246296
})
297+
298+
it('sets state for props passed as undefined by the parent', () => {
299+
consoleUtil.disableOnce()
300+
301+
const props = makeProps()
302+
const autoControlledProps = _.keys(props)
303+
304+
const randomProp = _.sample(autoControlledProps)
305+
306+
TestClass = createTestClass({ autoControlledProps, state: {} })
307+
const wrapper = shallow(<TestClass {...props} />)
308+
309+
wrapper
310+
.setProps({ [randomProp]: undefined })
311+
312+
wrapper
313+
.should.have.state(randomProp, props[randomProp])
314+
})
315+
316+
it('does not set state for props passed as null by the parent', () => {
317+
consoleUtil.disableOnce()
318+
319+
const props = makeProps()
320+
const autoControlledProps = _.keys(props)
321+
322+
const randomProp = _.sample(autoControlledProps)
323+
324+
TestClass = createTestClass({ autoControlledProps, state: {} })
325+
const wrapper = shallow(<TestClass {...props} />)
326+
327+
wrapper
328+
.setProps({ [randomProp]: null })
329+
330+
wrapper
331+
.should.have.state(randomProp, null)
332+
})
247333
})
248334
})

0 commit comments

Comments
 (0)