diff --git a/source/components/CurrencyInput/CurrencyInput.js b/source/components/CurrencyInput/CurrencyInput.js
index 0203aaef0..898f50d7b 100644
--- a/source/components/CurrencyInput/CurrencyInput.js
+++ b/source/components/CurrencyInput/CurrencyInput.js
@@ -24,8 +24,8 @@ let currencyFormat = language => ({
class CurrencyInput extends Component {
state = {
- value: this.props.value || '',
- valueHasChanged: false,
+ value: this.props.value,
+ initialValue: this.props.value
}
onChange = this.props.debounce
@@ -50,6 +50,14 @@ class CurrencyInput extends Component {
this.onChange(event)
}
+ // See https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#alternative-1-reset-uncontrolled-component-with-an-id-prop
+ static getDerivedStateFromProps({ value }, { initialValue }) {
+ if (value !== initialValue) {
+ return { value, initialValue: value }
+ }
+ return null
+ }
+
render() {
let forwardedProps = omit(
['onChange', 'defaultValue', 'language', 'className', 'value'],
@@ -62,6 +70,9 @@ class CurrencyInput extends Component {
decimalSeparator
} = currencyFormat(this.props.language)
+ // We display negative numbers iff this was the provided value (but we allow the user to enter them)
+ const valueHasChanged = this.state.value !== this.state.initialValue
+
return (
{
- this.setState({valueHasChanged: true, value})
- this.value = value.toString().replace(/^\-/,'')
+ this.setState({ value })
+ this.value = value.toString().replace(/^\-/, '')
this.handleNextChange = true
}}
onChange={this.handleChange}
- value={this.state.value.toString()
+ value={(this.state.value || '')
+ .toString()
.replace('.', decimalSeparator)}
/>
{!isCurrencyPrefixed && <> €>}
diff --git a/source/components/CurrencyInput/CurrencyInput.test.js b/source/components/CurrencyInput/CurrencyInput.test.js
index cdee61c95..cd492910e 100644
--- a/source/components/CurrencyInput/CurrencyInput.test.js
+++ b/source/components/CurrencyInput/CurrencyInput.test.js
@@ -64,7 +64,7 @@ describe('CurrencyInput', () => {
it('should not call onChange while the decimal part is being written', () => {
let onChange = spy()
- const input = getInput()
+ const input = getInput()
input.simulate('change', { target: { value: '111,', focus: () => {} } })
expect(onChange).not.to.have.been.called
})
@@ -105,25 +105,23 @@ describe('CurrencyInput', () => {
clock.restore()
})
- it('should initialize with value of the storeValue prop', () => {
- const input = getInput()
- expect(input.prop('value')).to.eq(1)
+ it('should initialize with value of the value prop', () => {
+ const wrapper = shallow()
+ expect(wrapper.state('value')).to.eq(1)
})
- it('should update its value if the storeValue prop changes', () => {
- const wrapper = shallow()
- wrapper.setProps({ storeValue: 2 })
+ it('should update its value if the value prop changes', () => {
+ const wrapper = shallow()
+ wrapper.setProps({ value: 2 })
expect(wrapper.state('value')).to.equal(2)
})
- it('should not update state if the storeValue is the same as the current input value', () => {
- const wrapper = shallow(
- {}} />
- )
+
+ it('should not call onChange the value is the same as the current input value', () => {
+ let onChange = spy()
+ const wrapper = mount( {}} />)
const input = wrapper.find('input')
- input.simulate('change', { target: { value: '2000' } })
- const state1 = wrapper.state()
- wrapper.setProps({ storeValue: '2000' })
- const state2 = wrapper.state()
- expect(state1).to.equal(state2)
+ input.simulate('change', { target: { value: '2000', focus: () => {} } })
+ wrapper.setProps({ value: '2000' })
+ expect(onChange).not.to.have.been.called
})
})
diff --git a/source/components/TargetSelection.js b/source/components/TargetSelection.js
index 2648af962..a857f66e3 100644
--- a/source/components/TargetSelection.js
+++ b/source/components/TargetSelection.js
@@ -7,7 +7,7 @@ import withLanguage from 'Components/utils/withLanguage'
import withSitePaths from 'Components/utils/withSitePaths'
import { encodeRuleName } from 'Engine/rules'
import { compose, isEmpty, isNil, propEq } from 'ramda'
-import React, { Component, PureComponent, useRef } from 'react'
+import React, { Component, PureComponent } from 'react'
import { withTranslation } from 'react-i18next'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'