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:
two states
? 1 for Kg
and another for lb
sibling components
? If so, how would they go about updating each other's states
?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>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With