【问题标题】:React component props only changing after second onClick eventReact 组件道具仅在第二个 onClick 事件后更改
【发布时间】:2017-01-18 17:42:09
【问题描述】:

我最近学习了 react,我正在尝试创建一个计算器作为自己的学习练习。

目的是每当我点击一个数字按钮时,该值就会出现在输入组件中。到目前为止,我已经完成了这项工作,但该值仅在第二个 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;

任何帮助将不胜感激!

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    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

    【讨论】:

      【解决方案2】:

      this.setState 是异步的,那么 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),因此您可以这样做(注意我们刚刚写了:'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>
      

      更好的是你可以这样做而不是重复你自己 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>
              );
          }
      

      【讨论】:

        猜你喜欢
        • 2016-02-26
        • 1970-01-01
        • 2017-01-12
        • 2020-12-24
        • 1970-01-01
        • 1970-01-01
        • 2021-01-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多