一个反应组件中是否可以有两种状态
我正在尝试构建一个简单的单位转换器来练习 React.js.我希望能够更改一个单位的值,例如:Kg,并让另一个单位(例如:lb)在屏幕上自动更改.请看这个网站给你一个想法:http://www.convertunits.com/from/lb/to/kg
我有以下代码,它呈现但单位不更新.我想知道的是:
- 一个组件有
两种状态
是否准确?1 代表Kg
另一个用于lb
- 或者它们是否需要成为
兄弟组件
?如果是这样,他们将如何更新彼此的states
? - 如果可以在同一个组件中同时拥有两个单元的状态,我在这里做错了什么?
谢谢!(我有一个简单的快速应用程序来呈现页面)
从'react'导入反应;导出默认类转换器扩展 React.Component {使成为() {返回 (<div className="convert"><范围/></div>);}}类范围扩展 React.Component {构造函数(道具){超级(道具);this.state = { kg: null, lb: null };}公斤点击(){this.setState({ lb: state.kg * 2.2046 });}磅点击(){this.setState({ kg: state.lb/2.2046 });}使成为() {返回 (<标签>公斤:</标签>
后端逻辑:
var express = require('express');var app = express();app.set('端口', (9000));app.set('视图引擎', 'jsx');app.set('views', __dirname + '/views');app.engine('jsx', require('express-react-views').createEngine({ transformViews: false }));要求('通天塔/注册')({忽略:假});app.use('/', function(req, res) {res.render('index', "");});app.listen(app.get('port'), function() {});
解决方案 是的,在 React 组件中拥有多个 state 属性是完全有效的(而且通常是必要的).
您的主要问题是您永远不会将点击事件实例传递给处理函数.因此,该函数无法知道数字输入的值.此外,您需要更新函数中两个测量的状态.这是因为您将数字输入的值设置为等于该值的状态.当您更改输入中的数字时,除非您还更新状态,否则它实际上不会在该输入的呈现中发生更改.最后,正如 mattclemens 指出的那样,您应该确保正确绑定 this
.要么将它绑定到组件实例上(就像我在下面做的那样),要么在你的处理函数中使用 ES6 箭头符号.
考虑到所有这些,如果您的课程看起来像这样,您的课程将可以正常工作:
class Range 扩展 React.Component {构造函数(道具){超级(道具);this.state = { kg: 0, lb: 0 };}kgClick(e) {var newLb = e.target.value * 2.2046;this.setState({ kg: e.target.value, lb: newLb });}磅点击(e){var newKg = e.target.value/2.2046;this.setState({ lb: e.target.value, kg: newKg });}使成为() {返回 (<标签>公斤:</标签>
I'm trying to build a simple unit convertor to practice React.js. I want to be able to change the value of one unit eg: Kg, and have the other unit eg: lb to automatically change on the screen. Please see this website to give you an idea: http://www.convertunits.com/from/lb/to/kg
I have the following code, it renders but the units don't update. What I want to know is:
- Is it even accurate for one component to have
two states
? 1 forKg
and another forlb
- Or would they need to be
sibling components
? If so, how would they go about updating each other'sstates
? - If it's possible to have the state for both units in the same component, what am I doing wrong here?
Thank you! (I have a simple express app to render the page)
import React from 'react';
export default class Converter extends React.Component {
render() {
return (
<div className="convert">
<Range />
</div>
);
}
}
class Range extends React.Component {
constructor(props) {
super(props);
this.state = { kg: null, lb: null };
}
kgClick() {
this.setState({ lb: state.kg * 2.2046 });
}
lbClick() {
this.setState({ kg: state.lb / 2.2046 });
}
render() {
return (
<div>
<label> Kg: </label>
<input type="number" name="Kg" onChange={this.kgClick} value={this.state.kg} />
<label> Lb: </label>
<input type="number" name="Lb" onChange={this.lbClick} value={this.state.lb} />
</div>
);
}
}
Backend logic:
var express = require('express');
var app = express();
app.set('port', (9000));
app.set('view engine', 'jsx');
app.set('views', __dirname + '/views');
app.engine('jsx', require('express-react-views').createEngine({ transformViews: false }));
require('babel/register')({
ignore: false
});
app.use('/', function(req, res) {
res.render('index', "");
});
app.listen(app.get('port'), function() {});
解决方案
Yes, it is perfectly valid (and often necessary) to have more than one state property in a React component.
Your main problem is that you are never passing your click event instance to the handler function. Therefore, that function has no way of knowing the value of the number input. Also, you need to update the state for both measurements in your function. This is because you are setting the value for your number inputs to equal the state of that value. When you change the number in the input, it will not actually change in the render of that input unless you also update the state. Finally, as mattclemens points out, you should make sure you are binding this
correctly. Either bind it on the component instance (like I do below) or use ES6 arrow notation in your handler function.
With all of that in mind, your class will work if it looks something like this:
class Range extends React.Component {
constructor(props) {
super(props);
this.state = { kg: 0, lb: 0 };
}
kgClick(e) {
var newLb = e.target.value * 2.2046;
this.setState({ kg: e.target.value, lb: newLb });
}
lbClick(e) {
var newKg = e.target.value / 2.2046;
this.setState({ lb: e.target.value, kg: newKg });
}
render() {
return (
<div>
<label> Kg: </label>
<input type="number" name="Kg" onChange={this.kgClick.bind(this)} value={this.state.kg} />
<label> Lb: </label>
<input type="number" name="Lb" onChange={this.lbClick.bind(this)} value={this.state.lb} />
</div>
);
}
}
相关文章