Reactでつくる割り勘電卓

  • 2
    いいね
  • 0
    コメント

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

CodePen デモ
GitHub

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

*その他 React記事
Reactおみくじ

 Hello World

Hello Worldを表示させた状態からはじめます。
*Hello World、表示環境の簡単なつくりかたはこちらで。

コード

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

コードの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

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

おわり

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

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