Reactでつくる割り勘電卓

Reactで簡単な割り勘電卓をつくってみました。

[CodePen](http://codepen.io/may88/pen/PWOPgN?editors=0010)　デモ
[GitHub](https://github.com/may88seiji/React-Split-calculator)

この記事ではReactで割り勘電卓をつくる手順をまとめていこうと思います。
全体の流れとしては下記になります。
1 合計金額、人数を入力し、値を保存・更新できるようにする。
2 入力された値をもとに計算する関数を作成する。
3 計算結果を出力できるようにする。

*その他　React記事
[Reactおみくじ](http://qiita.com/may88seiji/items/67b8ed01ad3101dded46)

##　Hello World
Hello Worldを表示させた状態からはじめます。 
*Hello World、表示環境の簡単なつくりかたは[こちら](http://qiita.com/may88seiji/items/648f7e550538168f18f1)で。

コード

```index.html
  <div id="root"></div>
```

```style.css
body{
    background: #f2f2f2;
    text-align: center;
    color: #000;
}
#root{
    font-size: 20px;
    font-weight: bold;
}
#root div{
    padding: 10px;
}
#root p{
  display:inline;
    padding: 20px;
}
.show{
  display:block;
}
input{text-align:right;
  padding:6px; 
}
.result{width: 350px;
    margin: 0 auto;}
```

```script.js
var Split = React.createClass({
//1
//2
//3
  render: function(){
    return (
     <div>
        <p>Hello World</p> 
     </div>
    );
  }
});

ReactDOM.render(
  <Split />,
  document.getElementById('root')
);
```

##1 合計金額、人数を入力し、値を保存・更新できるようにする。
`<p>Hello World</p>`を下記コードで置き換えます。 


```script.js
                <p>割り勘電卓</p>
                <div>
                    <p>合計</p>
                    <input type='text' placeholder='0' onChange={this.handleOnChangeTotal} /> 円
                </div>
                <div>
                    <p>人数</p>
                    <input type='text' placeholder='0' onChange={this.handleOnChangePeople} /> 人
                </div>
```

`<input />`は閉じる/が必要なので忘れないようにしてください。
このように入力フォームができると思いますが、値の保存などはできません。
![スクリーンショット 2017-01-28 12.20.05.png](https://qiita-image-store.s3.amazonaws.com/0/154186/1d6077f9-3b03-7074-e30b-6a04dd0ca6b4.png)

コードの`onChange`の部分に注目してください。
onChangeは値が変更されたときにイベントが発生し、紐づけられたfunctionが呼び出されます。（この場合、this.handleOnChangeTotalとthis.handleOnChangePeople）

次にonChangeによって呼び出されるfunctionを設定したいところですが、先に保存する値を初期設定します。
下記コードを//1の行に上書きします。

```script.js
    getInitialState:function(){
        return{total:0,
               people:0};
    },
```

`getInitialState`によって合計金額(total)、人数(people)で入力する値を0で初期設定します。

初期設定ができたので、onChageによって値を更新するfunctionを設定します。
下記コードを//2に上書きします。

```script.js
    handleOnChangeTotal:function(event){
        this.setState({
            total: event.target.value
        });
    },

    handleOnChangePeople:function(event){
        this.setState({
            people: event.target.value
        });
    },
```


`handleOnChangeTotal`はfunctionの名前。
`setState`はgetInitialStateで設定した値を保存、更新する場所になります。thisは現在のコンポーネント(var Split)であることを示します。

引数に`event`の変数が設定してあるのは、onChangeイベントで発生したオブジェクトを引き渡していて、`引数.target`とすることでイベントの発生したDOMオブジェクトを表すことができます。最後に`.value`を置くことで入力された値を得ることができます。

ここまできたら一度、値の保存・更新ができているのか確認してみます。
下記コードを`<p>割り勘電卓</p>`の下の行に追加してください。

```script.js
                <p>{this.state.total}</p>
                <p>{this.state.people}</p>
```

こんな感じで入力した値が連動すると思います。
![スクリーンショット 2017-01-28 12.55.00.png](https://qiita-image-store.s3.amazonaws.com/0/154186/d3d1752c-6a20-ed1c-2ef9-c5acf217017f.png)

##2 入力された値をもとに計算する関数を作成する。
割り勘計算をするfunctionを設定します。
下記コードを//3に上書きしてください。

```script.js
    caluculate:function(){
            var price = this.state.total;
            var num = this.state.people;
            var x1, x2, y1, y2;
            var unit = 100;
            var resultMoney;
            if (price.match(/^[1-9][0-9]*$/) && num.match(/^[1-9][0-9]*$/)) {
                if (price % num === 0) {
                    resultMoney = '一人 ' + (price / num) + ' 円';
                    this.setState({result:resultMoney});
                } else {
                    x1 = Math.floor(price / num / unit) * unit;
                    y1 = price - (x1 * num);
                    x2 = Math.ceil(price / num / unit) * unit;
                    y2 = Math.abs(price - (x2 * num));
                    resultMoney =
                    '一人 ' + x1 + ' 円だと ' + y1 + ' 円足りません。' +
                    '一人 ' + x2 + ' 円だと ' + y2 + ' 円余ります。';
                    this.setState({result:resultMoney});
                }
            } else {
                    resultMoney = 'error';
                    this.setState({result:resultMoney});
            }
    },
```
変数`price, num`に入力した値をstateから渡しています。
`resultMoney`は計算結果の金額を入れる変数です。
ここで新しく保存・更新したい値がでてきたのでgetInitialStateに`result `の項目を追加します。

```script.jsx
    getInitialState:function(){
        return{total:0,
               people:0,
               result:''};
    },
```

・if文
if文では正規表現で正の整数であるか判定し、条件分岐しています。
正の整数である場合は、更にif文で割り切れるか判定してtrueならばresultMoneyに計算結果を代入します。(falseならば、いくら余分に払うのか表示します。)
各分岐の最後に`this.setState({result:resultMoney});`といれることで割り切れない場合や、エラーのときの結果も更新されます。


##3 計算結果を出力できるようにする。
最後に計算を実行するイベント、出力のため設定をします。
下記コードを全体を包むdiv要素の内の一番下に追加してください。

```script.js
                <input type='button' value='計算する' onClick={this.caluculate} />
                <div className='result'>{this.state.result}</div>
```

` <input type='button' value='計算する' />`でボタンが追加され、`onClick={this.caluculate} `とすることでクリックしたときに、このコンポーネントのcaluculateが呼び出されます。
`<div className='result'></div>`のなかに`{this.state.result}`と置くことでstateのresultの値が表示されます。
一度、値を入れてみてください。

![スクリーンショット 2017-01-28 13.22.35.png](https://qiita-image-store.s3.amazonaws.com/0/154186/33a20829-f314-dc74-d882-b939be7f56d1.png)

##おわり
以上で簡単な割り勘電卓の作成手順の説明を終わります。
不明な点、補足がありましたらコメントいただけると助かります。
ありがとうございました。

```script.js
var Split = React.createClass({
    getInitialState:function(){
        return{total:0,
               people:0,
               result:''};
    },

    handleOnChangeTotal:function(event){
        this.setState({
            total: event.target.value
        });
    },

    handleOnChangePeople:function(event){
        this.setState({
            people: event.target.value
        });
    },

    caluculate:function(){
            var price = this.state.total;
            var num = this.state.people;
            var x1, x2, y1, y2;
            var unit = 100;
            var resultMoney;
            if (price.match(/^[1-9][0-9]*$/) && num.match(/^[1-9][0-9]*$/)) {
                if (price % num === 0) {
                    resultMoney = '一人 ' + (price / num) + ' 円';
            this.setState({result:resultMoney});
                } else {
                    x1 = Math.floor(price / num / unit) * unit;
                    y1 = price - (x1 * num);
                    x2 = Math.ceil(price / num / unit) * unit;
                    y2 = Math.abs(price - (x2 * num));
                    resultMoney =
                    '一人 ' + x1 + ' 円だと ' + y1 + ' 円足りません。' +
                    '一人 ' + x2 + ' 円だと ' + y2 + ' 円余ります。';
                    this.setState({result:resultMoney});
                }
            } else {
                    resultMoney = 'error';
                    this.setState({result:resultMoney});
            }
    },

    render:function(){
        return(
            <div>
                <p>割り勘電卓</p>
                <div>
                    <p>合計</p>
                    <input type='text' placeholder='0' onChange={this.handleOnChangeTotal} /> 円
                </div>
                <div>
                    <p>人数</p>
                    <input type='text' placeholder='0' onChange={this.handleOnChangePeople} /> 人
                </div>
                <input type='button' value='計算する' onClick={this.caluculate} />
                <div className='result'>{this.state.result}</div>
            </div>
        );
    }
});

ReactDOM.render(
  <Split />,
  document.getElementById('root')
);
```