React组件道具仅在第二次onClick事件

时间:2017-01-18 17:42:10

标签: javascript reactjs

我最近选择了反应,我正在尝试创建一个计算器作为我自己的倾斜练习。

目标是每当我点击数字按钮时,该值将出现在输入组件中。到目前为止,我已经有了这个工作,但值只会在第二个onClick事件上发生变化。

目前,val1道具在第一次点击时从输入中消失,然后在第二次点击时使用上一个按钮值重新出现。

关于我的代码结构的任何提示都非常受欢迎,并且随着我的计算器构建的任何指导也会很棒。我对此仍然很陌生。

以下是我的代码:

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;

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:3)

setState是一个异步函数,意味着只有在调用onChange回调函数后才会更新数据。因此,App Component仍然会获得旧值this.state.number

尝试在setState完成后调用onChange函数:

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

答案 1 :(得分:1)

this.setState是async,然后是this.props.onChange(this.state.number);在状态真正改变之前被调用,因此state.number具有旧值,你应该这样做: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
    }

顺便提一句,你可以将它添加到构造函数中:this.number = this.number.bind(this)因此你可以这样做(注意我们刚写了:&#39; this.number&#39;):

  <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>

更好的是你可以做到这一点,而不是重复你的自我9次:

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>
        );
    }