在 React 中输入 html 时在美分和美元之间进行转换
translating between cents and dollars in html input in React
我的情况有点奇怪,我在 we 应用程序中处理货币。在模型方面,我在发送到服务器之前将货币保存为美分,因为我不想在服务器端处理小数点。
但是在视图中,我希望显示正常货币而不是美分。
所以,我有这个输入字段,我从美元中获取数据并将其更改为美分:
<input name="balance" type="number" step="0.01" min="0"
placeholder="Balance in cents" onChange={this.handleUpdate}
value={this.props.user.balance / 100} />
当输入值发生变化时,我会在向上游发送之前将其改回美分:
handleUpdate: function(e) {
var value = e.target.value;
// changing it back from cents to dollars
value = parseFloat(value) * 100;
// save back to the parent component managing the prop
this.props.onUserUpdate(value);
}
这让我陷入了一种僵局,我无法输入小数点“。”让我演示一下:
33
input box --> 变成 3300
in the parent state --> back as 33
in component prop - 都很好
33.3
在输入框中 --> 在父状态中变为 3330
--> 在组件 prop 中返回为 33.3
- 很好
33.
在输入框中 --> 在父状态中变为 3300
--> 在组件 prop 中返回为 33
- 这就是问题所在
正如您在案例 #3 中看到的那样,当用户首次输入“.”时。这不会转换回与“.”相同的数字。
既然是受控输入,基本没法写"."
我试过使用不受控制的元素 defaultValue
,但是在渲染组件时 amount 属性还没有准备好,所以它只是空的
使用派生值的受控输入可能很棘手 - 如果您需要能够显示无效或其他奇怪的输入,那么...
始终将输入的 value
保留在其组件自己的 state
中
<input value={this.state.value} onChange={this.handleUpdate} // rest as above...
导出getInitialState()
中的初始value
getInitialState: function() {
return {value: this.props.user.balance / 100}
}
实现 componentWillReceiveProps(nextProps)
以检测 prop 的值何时从上方发生变化并重新导出状态值
componentWillReceiveProps: function(nextProps) {
if (this.props.user.balance != nextProps.user.balance) {
this.setState({value: nextProps.user.balance / 100})
}
}
现在,当用户输入“33.”时,您使用 setState()
存储他们的文字输入,然后回调给父级。
handleUpdate: function(e) {
var value = e.target.value
this.setState({value: value})
this.props.onUserUpdate(parseFloat(value) * 100)
}
如果父级通过 props 传递回子级的值没有改变(3300 == 3300
在这种情况下),那么 componentWillReceiveProps()
不会做任何事情。
工作片段:
<script src="http://fb.me/react-with-addons-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
<div id="example"></div>
<script type="text/jsx;harmony=true">void function() { 'use strict';
var Parent = React.createClass({
getInitialState() {
return {cents: 3300}
},
_changeValue() {
this.setState({cents: Math.round(Math.random() * 2000 + Math.random() * 2000)})
},
_onCentsChange(cents) {
this.setState({cents})
},
render() {
return <div>
<p><strong>Cents:</strong> {this.state.cents.toFixed(0)} <input type="button" onClick={this._changeValue} value="Change"/></p>
<Child cents={this.state.cents} onCentsChange={this._onCentsChange}/>
</div>
}
})
var Child = React.createClass({
getInitialState() {
return {dollars: this.props.cents / 100}
},
componentWillReceiveProps(nextProps) {
if (this.props.cents != nextProps.cents) {
this.setState({dollars: nextProps.cents / 100})
}
},
_onChange(e) {
var dollars = e.target.value
this.setState({dollars})
if (!isNaN(parseFloat(dollars)) && isFinite(dollars)) {
this.props.onCentsChange(parseFloat(dollars) * 100)
}
},
render() {
return <div>
<input type="number" step="0.01" min="0" value={this.state.dollars} onChange={this._onChange}/>
</div>
}
})
React.render(<Parent/>, document.querySelector('#example'))
}()</script>
我正在使用这个简单的解决方案来处理受控输入和十进制值。
在您的状态下创建两个道具,一个保存实际值,另一个保存字符串。
constructor(props) {
....
this.state = {
myProperty: 1.42,
myPropertyString: '1.42'
}
}
将您的输入值设置为字符串一
<input type="text"
onChange={this.handleUpdate}
value={this.state.myPropertyString}/>
在handleUpdate方法中更新两个状态变量。
handleUpdate(e) {
this.setState({
myProperty: parseFloat(e.target.value),
myPropertyString: e.target.value
});
}
我的情况有点奇怪,我在 we 应用程序中处理货币。在模型方面,我在发送到服务器之前将货币保存为美分,因为我不想在服务器端处理小数点。 但是在视图中,我希望显示正常货币而不是美分。
所以,我有这个输入字段,我从美元中获取数据并将其更改为美分:
<input name="balance" type="number" step="0.01" min="0"
placeholder="Balance in cents" onChange={this.handleUpdate}
value={this.props.user.balance / 100} />
当输入值发生变化时,我会在向上游发送之前将其改回美分:
handleUpdate: function(e) {
var value = e.target.value;
// changing it back from cents to dollars
value = parseFloat(value) * 100;
// save back to the parent component managing the prop
this.props.onUserUpdate(value);
}
这让我陷入了一种僵局,我无法输入小数点“。”让我演示一下:
33
input box --> 变成3300
in the parent state --> back as33
in component prop - 都很好33.3
在输入框中 --> 在父状态中变为3330
--> 在组件 prop 中返回为33.3
- 很好33.
在输入框中 --> 在父状态中变为3300
--> 在组件 prop 中返回为33
- 这就是问题所在
正如您在案例 #3 中看到的那样,当用户首次输入“.”时。这不会转换回与“.”相同的数字。
既然是受控输入,基本没法写"."
我试过使用不受控制的元素 defaultValue
,但是在渲染组件时 amount 属性还没有准备好,所以它只是空的
使用派生值的受控输入可能很棘手 - 如果您需要能够显示无效或其他奇怪的输入,那么...
始终将输入的
中value
保留在其组件自己的state
<input value={this.state.value} onChange={this.handleUpdate} // rest as above...
导出
中的初始getInitialState()
value
getInitialState: function() { return {value: this.props.user.balance / 100} }
实现
componentWillReceiveProps(nextProps)
以检测 prop 的值何时从上方发生变化并重新导出状态值componentWillReceiveProps: function(nextProps) { if (this.props.user.balance != nextProps.user.balance) { this.setState({value: nextProps.user.balance / 100}) } }
现在,当用户输入“33.”时,您使用 setState()
存储他们的文字输入,然后回调给父级。
handleUpdate: function(e) {
var value = e.target.value
this.setState({value: value})
this.props.onUserUpdate(parseFloat(value) * 100)
}
如果父级通过 props 传递回子级的值没有改变(3300 == 3300
在这种情况下),那么 componentWillReceiveProps()
不会做任何事情。
工作片段:
<script src="http://fb.me/react-with-addons-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
<div id="example"></div>
<script type="text/jsx;harmony=true">void function() { 'use strict';
var Parent = React.createClass({
getInitialState() {
return {cents: 3300}
},
_changeValue() {
this.setState({cents: Math.round(Math.random() * 2000 + Math.random() * 2000)})
},
_onCentsChange(cents) {
this.setState({cents})
},
render() {
return <div>
<p><strong>Cents:</strong> {this.state.cents.toFixed(0)} <input type="button" onClick={this._changeValue} value="Change"/></p>
<Child cents={this.state.cents} onCentsChange={this._onCentsChange}/>
</div>
}
})
var Child = React.createClass({
getInitialState() {
return {dollars: this.props.cents / 100}
},
componentWillReceiveProps(nextProps) {
if (this.props.cents != nextProps.cents) {
this.setState({dollars: nextProps.cents / 100})
}
},
_onChange(e) {
var dollars = e.target.value
this.setState({dollars})
if (!isNaN(parseFloat(dollars)) && isFinite(dollars)) {
this.props.onCentsChange(parseFloat(dollars) * 100)
}
},
render() {
return <div>
<input type="number" step="0.01" min="0" value={this.state.dollars} onChange={this._onChange}/>
</div>
}
})
React.render(<Parent/>, document.querySelector('#example'))
}()</script>
我正在使用这个简单的解决方案来处理受控输入和十进制值。
在您的状态下创建两个道具,一个保存实际值,另一个保存字符串。
constructor(props) { .... this.state = { myProperty: 1.42, myPropertyString: '1.42' } }
将您的输入值设置为字符串一
<input type="text" onChange={this.handleUpdate} value={this.state.myPropertyString}/>
在handleUpdate方法中更新两个状态变量。
handleUpdate(e) { this.setState({ myProperty: parseFloat(e.target.value), myPropertyString: e.target.value }); }