Skip to content

Commit 8105906

Browse files
drobannxKent C. Dodds
authored andcommitted
fix(internalSetState): dont change references inside setState updater (#423)
* fix(internalSetState): dont change references inside setState updater function * fix(internalSetState): remove change to arg passed to updater function * fix(internalSetState): add failing test case
1 parent 8695998 commit 8105906

File tree

4 files changed

+50
-16
lines changed

4 files changed

+50
-16
lines changed

.all-contributorsrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,15 @@
738738
"contributions": [
739739
"example"
740740
]
741+
},
742+
{
743+
"login": "drobannx",
744+
"name": "Brandon Clemons",
745+
"avatar_url": "https://avatars2.githubusercontent.com/u/6361167?v=4",
746+
"profile": "https://github.com/drobannx",
747+
"contributions": [
748+
"code"
749+
]
741750
}
742751
]
743752
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ autocomplete/dropdown/select/combobox components</p>
1919
[![downloads][downloads-badge]][npmcharts] [![version][version-badge]][package]
2020
[![MIT License][license-badge]][license]
2121

22-
[![All Contributors](https://img.shields.io/badge/all_contributors-74-orange.svg?style=flat-square)](#contributors)
22+
[![All Contributors](https://img.shields.io/badge/all_contributors-75-orange.svg?style=flat-square)](#contributors)
2323
[![PRs Welcome][prs-badge]][prs] [![Chat][chat-badge]][chat]
2424
[![Code of Conduct][coc-badge]][coc]
2525

@@ -956,7 +956,7 @@ Thanks goes to these people ([emoji key][emojis]):
956956
| [<img src="https://avatars2.githubusercontent.com/u/1556430?v=4" width="100px;"/><br /><sub><b>Pete Redmond</b></sub>](https://httpete.com)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3Ahttpete-ire "Bug reports") | [<img src="https://avatars2.githubusercontent.com/u/1706342?v=4" width="100px;"/><br /><sub><b>Nick Lavin</b></sub>](https://github.com/Zashy)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3AZashy "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=Zashy "Code") [⚠️](https://github.com/paypal/downshift/commits?author=Zashy "Tests") | [<img src="https://avatars2.githubusercontent.com/u/17031?v=4" width="100px;"/><br /><sub><b>James Long</b></sub>](http://jlongster.com)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3Ajlongster "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=jlongster "Code") | [<img src="https://avatars0.githubusercontent.com/u/1505907?v=4" width="100px;"/><br /><sub><b>Michael Ball</b></sub>](http://michaelball.co)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3Acycomachead "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=cycomachead "Code") | [<img src="https://avatars0.githubusercontent.com/u/8990614?v=4" width="100px;"/><br /><sub><b>CAVALEIRO Julien</b></sub>](https://github.com/Julienng)<br />[💡](#example-Julienng "Examples") | [<img src="https://avatars1.githubusercontent.com/u/3421067?v=4" width="100px;"/><br /><sub><b>Kim Grönqvist</b></sub>](http://www.kimgronqvist.se)<br />[💻](https://github.com/paypal/downshift/commits?author=kimgronqvist "Code") [⚠️](https://github.com/paypal/downshift/commits?author=kimgronqvist "Tests") | [<img src="https://avatars2.githubusercontent.com/u/3675602?v=4" width="100px;"/><br /><sub><b>Sijie</b></sub>](http://sijietian.com)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3Atiansijie "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=tiansijie "Code") |
957957
| [<img src="https://avatars0.githubusercontent.com/u/410792?v=4" width="100px;"/><br /><sub><b>Dony Sukardi</b></sub>](http://dsds.io)<br />[💡](#example-donysukardi "Examples") [💬](#question-donysukardi "Answering Questions") [💻](https://github.com/paypal/downshift/commits?author=donysukardi "Code") [⚠️](https://github.com/paypal/downshift/commits?author=donysukardi "Tests") | [<img src="https://avatars1.githubusercontent.com/u/2755722?v=4" width="100px;"/><br /><sub><b>Dillon Mulroy</b></sub>](https://dillonmulroy.com)<br />[📖](https://github.com/paypal/downshift/commits?author=dmmulroy "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/12440573?v=4" width="100px;"/><br /><sub><b>Curtis Tate Wilkinson</b></sub>](https://twitter.com/curtytate)<br />[💻](https://github.com/paypal/downshift/commits?author=curtiswilkinson "Code") | [<img src="https://avatars3.githubusercontent.com/u/383212?v=4" width="100px;"/><br /><sub><b>Brice BERNARD</b></sub>](https://github.com/brikou)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3Abrikou "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=brikou "Code") | [<img src="https://avatars3.githubusercontent.com/u/14304503?v=4" width="100px;"/><br /><sub><b>Tony Xu</b></sub>](https://github.com/xutopia)<br />[💻](https://github.com/paypal/downshift/commits?author=xutopia "Code") | [<img src="https://avatars1.githubusercontent.com/u/14035529?v=4" width="100px;"/><br /><sub><b>Anthony Ng</b></sub>](http://anthonyng.me)<br />[📖](https://github.com/paypal/downshift/commits?author=newyork-anthonyng "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/11996139?v=4" width="100px;"/><br /><sub><b>S S</b></sub>](https://github.com/notruth)<br />[💬](#question-notruth "Answering Questions") [💻](https://github.com/paypal/downshift/commits?author=notruth "Code") [📖](https://github.com/paypal/downshift/commits?author=notruth "Documentation") [🤔](#ideas-notruth "Ideas, Planning, & Feedback") [⚠️](https://github.com/paypal/downshift/commits?author=notruth "Tests") |
958958
| [<img src="https://avatars0.githubusercontent.com/u/29493001?v=4" width="100px;"/><br /><sub><b>Austin Tackaberry</b></sub>](http://austintackaberry.co)<br />[💬](#question-austintackaberry "Answering Questions") [💻](https://github.com/paypal/downshift/commits?author=austintackaberry "Code") [📖](https://github.com/paypal/downshift/commits?author=austintackaberry "Documentation") [🐛](https://github.com/paypal/downshift/issues?q=author%3Aaustintackaberry "Bug reports") [💡](#example-austintackaberry "Examples") [🤔](#ideas-austintackaberry "Ideas, Planning, & Feedback") [👀](#review-austintackaberry "Reviewed Pull Requests") [⚠️](https://github.com/paypal/downshift/commits?author=austintackaberry "Tests") | [<img src="https://avatars3.githubusercontent.com/u/4168055?v=4" width="100px;"/><br /><sub><b>Jean Duthon</b></sub>](https://github.com/jduthon)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3Ajduthon "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=jduthon "Code") | [<img src="https://avatars3.githubusercontent.com/u/3889580?v=4" width="100px;"/><br /><sub><b>Anton Telesh</b></sub>](http://antontelesh.github.io)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3AAntontelesh "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=Antontelesh "Code") | [<img src="https://avatars3.githubusercontent.com/u/1060669?v=4" width="100px;"/><br /><sub><b>Eric Edem</b></sub>](https://github.com/ericedem)<br />[💻](https://github.com/paypal/downshift/commits?author=ericedem "Code") [📖](https://github.com/paypal/downshift/commits?author=ericedem "Documentation") [🤔](#ideas-ericedem "Ideas, Planning, & Feedback") [⚠️](https://github.com/paypal/downshift/commits?author=ericedem "Tests") | [<img src="https://avatars3.githubusercontent.com/u/3409645?v=4" width="100px;"/><br /><sub><b>Austin Wood</b></sub>](https://github.com/indiesquidge)<br />[💬](#question-indiesquidge "Answering Questions") [📖](https://github.com/paypal/downshift/commits?author=indiesquidge "Documentation") [👀](#review-indiesquidge "Reviewed Pull Requests") | [<img src="https://avatars3.githubusercontent.com/u/14275790?v=4" width="100px;"/><br /><sub><b>Mark Murray</b></sub>](https://github.com/mmmurray)<br />[🚇](#infra-mmmurray "Infrastructure (Hosting, Build-Tools, etc)") | [<img src="https://avatars0.githubusercontent.com/u/1862172?v=4" width="100px;"/><br /><sub><b>Gianmarco</b></sub>](https://github.com/gsimone)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3Agsimone "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=gsimone "Code") |
959-
| [<img src="https://avatars2.githubusercontent.com/u/6838136?v=4" width="100px;"/><br /><sub><b>Emmanuel Pastor</b></sub>](https://github.com/pastr)<br />[💡](#example-pastr "Examples") | [<img src="https://avatars2.githubusercontent.com/u/10345034?v=4" width="100px;"/><br /><sub><b>dalehurwitz</b></sub>](https://github.com/dalehurwitz)<br />[💻](https://github.com/paypal/downshift/commits?author=dalehurwitz "Code") | [<img src="https://avatars1.githubusercontent.com/u/4813007?v=4" width="100px;"/><br /><sub><b>Bogdan Lobor</b></sub>](https://github.com/blobor)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3Ablobor "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=blobor "Code") | [<img src="https://avatars0.githubusercontent.com/u/1127238?v=4" width="100px;"/><br /><sub><b>Luke Herrington</b></sub>](https://github.com/infiniteluke)<br />[💡](#example-infiniteluke "Examples") |
959+
| [<img src="https://avatars2.githubusercontent.com/u/6838136?v=4" width="100px;"/><br /><sub><b>Emmanuel Pastor</b></sub>](https://github.com/pastr)<br />[💡](#example-pastr "Examples") | [<img src="https://avatars2.githubusercontent.com/u/10345034?v=4" width="100px;"/><br /><sub><b>dalehurwitz</b></sub>](https://github.com/dalehurwitz)<br />[💻](https://github.com/paypal/downshift/commits?author=dalehurwitz "Code") | [<img src="https://avatars1.githubusercontent.com/u/4813007?v=4" width="100px;"/><br /><sub><b>Bogdan Lobor</b></sub>](https://github.com/blobor)<br />[🐛](https://github.com/paypal/downshift/issues?q=author%3Ablobor "Bug reports") [💻](https://github.com/paypal/downshift/commits?author=blobor "Code") | [<img src="https://avatars0.githubusercontent.com/u/1127238?v=4" width="100px;"/><br /><sub><b>Luke Herrington</b></sub>](https://github.com/infiniteluke)<br />[💡](#example-infiniteluke "Examples") | [<img src="https://avatars2.githubusercontent.com/u/6361167?v=4" width="100px;"/><br /><sub><b>Brandon Clemons</b></sub>](https://github.com/drobannx)<br />[💻](https://github.com/paypal/downshift/commits?author=drobannx "Code") |
960960

961961
<!-- ALL-CONTRIBUTORS-LIST:END -->
962962

src/__tests__/downshift.misc.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,22 @@ test('can use children instead of render prop', () => {
116116
expect(childrenSpy).toHaveBeenCalledTimes(1)
117117
})
118118

119+
test('should not throw error during strict mode during reset', () => {
120+
let renderArg
121+
const renderFn = () => <div />
122+
const renderSpy = jest.fn(controllerArg => {
123+
renderArg = controllerArg
124+
return renderFn(controllerArg)
125+
})
126+
render(
127+
<React.StrictMode>
128+
<Downshift render={renderSpy} />
129+
</React.StrictMode>,
130+
)
131+
132+
renderArg.reset()
133+
})
134+
119135
test('can use setState for ultimate power', () => {
120136
const {renderSpy, setState} = setup()
121137
renderSpy.mockClear()

src/downshift.js

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -318,32 +318,38 @@ class Downshift extends Component {
318318
return this.setState(
319319
state => {
320320
state = this.getState(state)
321-
stateToSet = isStateToSetFunction ? stateToSet(state) : stateToSet
321+
let newStateToSet = isStateToSetFunction
322+
? stateToSet(state)
323+
: stateToSet
322324

323325
// Your own function that could modify the state that will be set.
324-
stateToSet = this.props.stateReducer(state, stateToSet)
326+
newStateToSet = this.props.stateReducer(state, newStateToSet)
325327

326328
// checks if an item is selected, regardless of if it's different from
327329
// what was selected before
328330
// used to determine if onSelect and onChange callbacks should be called
329-
isItemSelected = stateToSet.hasOwnProperty('selectedItem')
331+
isItemSelected = newStateToSet.hasOwnProperty('selectedItem')
330332
// this keeps track of the object we want to call with setState
331333
const nextState = {}
332334
// this is just used to tell whether the state changed
333335
const nextFullState = {}
334336
// we need to call on change if the outside world is controlling any of our state
335337
// and we're trying to update that state. OR if the selection has changed and we're
336338
// trying to update the selection
337-
if (isItemSelected && stateToSet.selectedItem !== state.selectedItem) {
338-
onChangeArg = stateToSet.selectedItem
339+
if (
340+
isItemSelected &&
341+
newStateToSet.selectedItem !== state.selectedItem
342+
) {
343+
onChangeArg = newStateToSet.selectedItem
339344
}
340-
stateToSet.type = stateToSet.type || Downshift.stateChangeTypes.unknown
345+
newStateToSet.type =
346+
newStateToSet.type || Downshift.stateChangeTypes.unknown
341347

342-
Object.keys(stateToSet).forEach(key => {
348+
Object.keys(newStateToSet).forEach(key => {
343349
// onStateChangeArg should only have the state that is
344350
// actually changing
345-
if (state[key] !== stateToSet[key]) {
346-
onStateChangeArg[key] = stateToSet[key]
351+
if (state[key] !== newStateToSet[key]) {
352+
onStateChangeArg[key] = newStateToSet[key]
347353
}
348354
// the type is useful for the onStateChangeArg
349355
// but we don't actually want to set it in internal state.
@@ -354,19 +360,22 @@ class Downshift extends Component {
354360
if (key === 'type') {
355361
return
356362
}
357-
nextFullState[key] = stateToSet[key]
363+
nextFullState[key] = newStateToSet[key]
358364
// if it's coming from props, then we don't care to set it internally
359365
if (!this.isControlledProp(key)) {
360-
nextState[key] = stateToSet[key]
366+
nextState[key] = newStateToSet[key]
361367
}
362368
})
363369

364370
// if stateToSet is a function, then we weren't able to call onInputValueChange
365371
// earlier, so we'll call it now that we know what the inputValue state will be.
366-
if (isStateToSetFunction && stateToSet.hasOwnProperty('inputValue')) {
367-
this.props.onInputValueChange(stateToSet.inputValue, {
372+
if (
373+
isStateToSetFunction &&
374+
newStateToSet.hasOwnProperty('inputValue')
375+
) {
376+
this.props.onInputValueChange(newStateToSet.inputValue, {
368377
...this.getStateAndHelpers(),
369-
...stateToSet,
378+
...newStateToSet,
370379
})
371380
}
372381

0 commit comments

Comments
 (0)