2017-01-18 7 views
1

最近私は反応を取り上げました。自分自身のための訓練として、電卓を作成しようとしています。2番目のonClickイベントの後に反応コンポーネントの小道具のみが変更されます

数値ボタンをクリックするたびに、その値が入力コンポーネントに表示されます。今まで私はこれを動作させましたが、値は2番目のonClickイベントでのみ変更されます。

現在、val1小道具は最初のクリック時に入力から消え、2番目のクリック時に前のボタン値で再び表示されます。

私のコードの構造に関するヒントは歓迎されず、私の電卓のビルドを進める上でのガイダンスも素晴らしいでしょう。私はまだこれに新しいです。ここで

は、以下の私のコードです:

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

setStateは非同期関数です。つまり、データはonChangeコールバック関数を呼び出した後にのみ更新されます。したがって、Appコンポーネントはまだ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

作品、目この( 'this.numberを私たちはちょうど書いたという通知)を行うことができますあなたはアンク! – AngryFridges

1

this.setStateはその後、非同期、this.props.onChange(this.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 
    } 

を、道によって、あなたは、コンストラクタにこれを追加することができます:状態は本当に変わっ前に呼び出され、ひいてはstate.numberは古い値を持っているされて,,あなたはこれを行う必要がありthis.number = this.number.bind(this)をし、結果としてあなた

<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> 
     ); 
    } 
関連する問題