admin管理员组文章数量:1317906
I've recently picked up react and I'm attempting to create a calculator as a leaning exercise for myself.
The aim is that whenever I click on a number button then that value will appear in the input ponent. So far I have got this to work but the value only changes on the second onClick event.
Currently the val1 prop disappears from the input on first click and then reappears on the second click with the previous button value.
Any tips on the structure of my code are more than wele and any guidance going forward with the build of my calculator would also be great. I am still very new to this.
Here's my code below:
app.js
import React, {Component} from 'react';
import InputField from './Components/InputField';
import Numbers from './Components/Numbers';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
number: 0,
val1: 0,
val2: 0
}
}
numberChange(num1, num2){
this.setState({val1: num1});
}
render() {
return (
<div className="App">
<InputField val1={this.state.val1} value={this.state.number || ''} onChange={this.numberChange.bind(this)} />
<Numbers onChange={this.numberChange.bind(this)} />
</div>
);
}
}
export default App;
InputField.js
import React, {Component} from 'react';
class InputField extends Component {
constructor(props) {
super(props);
this.state = {
number: 0
}
}
onChange(e) {
console.log('onChange event fired');
this.setState({
number: e.target.value
})
this.props.onChange(this.state.number);
console.log(this.state.number);
}
render() {
return (
<div className="inputField">
<input type="number" value={this.props.val1 || ''} onChange={this.onChange.bind(this)}/>
</div>
);
}
}
export default InputField;
Numbers.js
import React, {Component} from 'react';
import {Button} from 'react-bootstrap'
class Numbers extends Component {
constructor(props) {
super(props);
this.state = {
number: props.value
}
}
number(e) {
console.log('You\'ve pressed number ' + e.target.value);
this.setState({
number: e.target.value
})
this.props.onChange(this.state.number);
}
render() {
return (
<div className="buttons">
<Button bsStyle="primary" value="1" onClick={this.number.bind(this)}>1</Button>
<Button bsStyle="primary" value="2" onClick={this.number.bind(this)}>2</Button>
<Button bsStyle="primary" value="3" onClick={this.number.bind(this)}>3</Button>
<Button bsStyle="primary" value="4" onClick={this.number.bind(this)}>4</Button>
<Button bsStyle="primary" value="5" onClick={this.number.bind(this)}>5</Button>
<Button bsStyle="primary" value="6" onClick={this.number.bind(this)}>6</Button>
<Button bsStyle="primary" value="7" onClick={this.number.bind(this)}>7</Button>
<Button bsStyle="primary" value="8" onClick={this.number.bind(this)}>8</Button>
<Button bsStyle="primary" value="9" onClick={this.number.bind(this)}>9</Button>
</div>
);
}
}
export default Numbers;
Any help would be greatly appreciated!
I've recently picked up react and I'm attempting to create a calculator as a leaning exercise for myself.
The aim is that whenever I click on a number button then that value will appear in the input ponent. So far I have got this to work but the value only changes on the second onClick event.
Currently the val1 prop disappears from the input on first click and then reappears on the second click with the previous button value.
Any tips on the structure of my code are more than wele and any guidance going forward with the build of my calculator would also be great. I am still very new to this.
Here's my code below:
app.js
import React, {Component} from 'react';
import InputField from './Components/InputField';
import Numbers from './Components/Numbers';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
number: 0,
val1: 0,
val2: 0
}
}
numberChange(num1, num2){
this.setState({val1: num1});
}
render() {
return (
<div className="App">
<InputField val1={this.state.val1} value={this.state.number || ''} onChange={this.numberChange.bind(this)} />
<Numbers onChange={this.numberChange.bind(this)} />
</div>
);
}
}
export default App;
InputField.js
import React, {Component} from 'react';
class InputField extends Component {
constructor(props) {
super(props);
this.state = {
number: 0
}
}
onChange(e) {
console.log('onChange event fired');
this.setState({
number: e.target.value
})
this.props.onChange(this.state.number);
console.log(this.state.number);
}
render() {
return (
<div className="inputField">
<input type="number" value={this.props.val1 || ''} onChange={this.onChange.bind(this)}/>
</div>
);
}
}
export default InputField;
Numbers.js
import React, {Component} from 'react';
import {Button} from 'react-bootstrap'
class Numbers extends Component {
constructor(props) {
super(props);
this.state = {
number: props.value
}
}
number(e) {
console.log('You\'ve pressed number ' + e.target.value);
this.setState({
number: e.target.value
})
this.props.onChange(this.state.number);
}
render() {
return (
<div className="buttons">
<Button bsStyle="primary" value="1" onClick={this.number.bind(this)}>1</Button>
<Button bsStyle="primary" value="2" onClick={this.number.bind(this)}>2</Button>
<Button bsStyle="primary" value="3" onClick={this.number.bind(this)}>3</Button>
<Button bsStyle="primary" value="4" onClick={this.number.bind(this)}>4</Button>
<Button bsStyle="primary" value="5" onClick={this.number.bind(this)}>5</Button>
<Button bsStyle="primary" value="6" onClick={this.number.bind(this)}>6</Button>
<Button bsStyle="primary" value="7" onClick={this.number.bind(this)}>7</Button>
<Button bsStyle="primary" value="8" onClick={this.number.bind(this)}>8</Button>
<Button bsStyle="primary" value="9" onClick={this.number.bind(this)}>9</Button>
</div>
);
}
}
export default Numbers;
Any help would be greatly appreciated!
Share Improve this question asked Jan 18, 2017 at 17:42 AngryFridgesAngryFridges 4136 silver badges13 bronze badges2 Answers
Reset to default 5setState is an asynchronous function, meaning the data is only updated after you have called the onChange callback function. Therefore the App Component still gets the old value of this.state.number
.
Try calling the onChange function after the setState is finished by:
number(e) {
console.log('You\'ve pressed number ' + e.target.value);
this.setState({
number: e.target.value
}, () => {
this.props.onChange(this.state.number);
})
}
More info here
this.setState is async, then this.props.onChange(this.state.number); is called before the state really changed, and thus state.number has the old value,, you should do this: this.props.onChange(e.target.value);
number(e) {
console.log('You\'ve pressed number ' + e.target.value);
this.setState({
number: e.target.value
})
this.props.onChange(e.target.value); // check this
}
and by the way you can add this to the constructor: this.number = this.number.bind(this)
and as a result you can do this (notice that we just wrote :'this.number'):
<Button bsStyle="primary" value="1" onClick={this.number}>1</Button>
<Button bsStyle="primary" value="2" onClick={this.number}>2</Button>
<Button bsStyle="primary" value="3" onClick={this.number}>3</Button>
<Button bsStyle="primary" value="4" onClick={this.number}>4</Button>
<Button bsStyle="primary" value="5" onClick={this.number}>5</Button>
<Button bsStyle="primary" value="6" onClick={this.number}>6</Button>
<Button bsStyle="primary" value="7" onClick={this.number}>7</Button>
<Button bsStyle="primary" value="8" onClick={this.number}>8</Button>
<Button bsStyle="primary" value="9" onClick={this.number}>9</Button>
even better you can do this instead of repeating your self 9 times:
render() {
let buttons = []
for(var i =1; i <10; i++)
buttons.push(<Button bsStyle="primary" value={i} onClick={this.number}>{i}</Button>)
return (
<div className="buttons">
{buttons}
</div>
);
}
本文标签: javascriptReact component props only changing after second onClick eventStack Overflow
版权声明:本文标题:javascript - React component props only changing after second onClick event - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742031199a2416474.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论