简体   繁体   English

React 组件道具仅在第二个 onClick 事件后更改

[英]React component props only changing after second onClick event

I've recently picked up react and I'm attempting to create a calculator as a leaning exercise for myself.我最近开始学习 React,我正在尝试创建一个计算器作为自己的学习练习。

The aim is that whenever I click on a number button then that value will appear in the input component.目的是每当我单击数字按钮时,该值就会出现在输入组件中。 So far I have got this to work but the value only changes on the second onClick event.到目前为止,我已经让它工作了,但该值仅在第二个 onClick 事件上发生变化。

Currently the val1 prop disappears from the input on first click and then reappears on the second click with the previous button value.目前 val1 道具在第一次点击时从输入中消失,然后在第二次点击时重新出现,并带有前一个按钮值。

Any tips on the structure of my code are more than welcome 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应用程序.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输入字段.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数字.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!任何帮助将不胜感激!

setState is an asynchronous function, meaning the data is only updated after you have called the onChange callback function. setState 是一个异步函数,这意味着只有在调用 onChange 回调函数后才会更新数据。 Therefore the App Component still gets the old value of this.state.number .因此 App 组件仍然获得this.state.number的旧值。

Try calling the onChange function after the setState is finished by:尝试在 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 更多信息在这里

this.setState is async, then this.props.onChange(this.state.number); this.setState 是异步的,那么 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);在状态真正改变之前调用,因此 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
    }

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'):顺便说一下,您可以将其添加到构造函数中: this.number = this.number.bind(this)并且因此您可以这样做(注意我们刚刚写了 :'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:更好的是你可以这样做而不是重复你自己 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>
        );
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM