LoginSignup
5
7

More than 5 years have passed since last update.

Reactチュートリアルが難しすぎる人のためのReactチュートリアル2

Last updated at Posted at 2017-11-02

Reactチュートリアルが難しすぎる人のためのReactチュートリアル1
に引き続き、第二回。
チュートリアルだと思った?
僕のメモで、つよい人にこれでいいのか聞くための資料でした。残念だったね。

作るもの

https://gyazo.com/5923dda7777fd0beeddb9b9d057a4af1

年収表示部分を部品化

年収表示部分をIncome.tsxとして、部品化します。
今回は部品使用元から年収がPropsで渡されるのが大きな違いです。

Income.tsx
import * as React from "react";
import "./App.css";

export interface State {}
export interface Props {
  income: number;
}

class Income extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    // メソッド内でthisを見るためのお約束
    this.moneyYouWant = this.moneyYouWant.bind(this);
  }

  moneyYouWant(money: number): string {
    if (money === NaN || money <= 0) {
      return "";
    }
    return `${money * 10000000}兆円欲しい`;
  }

  render() {
    return <p className="Money">{this.moneyYouWant(this.props.income)}</p>;
  }
}

export default Income;

Income.tsxを使う

App.tsx
import * as React from "react";
import "./App.css";
import Income from "./Income";

export interface Props {}
export interface State {
  inputingIncome: string;
  incomes: Array<number>;
}
const logo = require("./logo.svg");

class App extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      inputingIncome: "",
      incomes: []
    };
    // メソッド内でthisを見るためのお約束
    this.addIncome = this.addIncome.bind(this);
    this.onChangeIncome = this.onChangeIncome.bind(this);
  }

  onChangeIncome(e: React.FormEvent<HTMLInputElement>) {
    this.setState({
      inputingIncome: e.currentTarget.value
    });
  }

  addIncome(e: React.FormEvent<HTMLButtonElement>) {
    let arr = this.state.incomes;
    let income = Number(this.state.inputingIncome);
    if (isNaN(income)) {
      return;
    }

    arr.unshift(income);
    this.setState({
      inputingIncome: "",
      incomes: arr
    });
  }

  render() {
    // keyを渡さないと警告がでた。index番号をkeyとした。
    let incomes = this.state.incomes.map((i, index) => {
      return <Income key={index} income={i} />;
    });
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          <label>
            現在の年収
            <input
              type="text"
              value={this.state.inputingIncome}
              onChange={this.onChangeIncome}
            />万          </label>
          <button onClick={this.addIncome}>年収追加</button>
        </p>
        {incomes}
      </div>
    );
  }
}

export default App;
  • テキストを編集するとonChangeIncomeが呼ばれ、 stateのinputingIncomeに保持されます。
  • 追加ボタンを押すと、addIncomeが呼ばれ、stateのincomes配列の先頭に追加されます。
  • あとはstateが更新される度に、viewが描画され、incomesのそれぞれに対して、Income.tsxを描画しています。

個人的ハマリポイント

部品の描画部品を呼び出したパラメータが

<Income key={index} income={i} />

Propsで以下のように受け取れる、

export interface Props {
  income: number;
}

というのが取っ付きづらいポイントかな、と思いました。

強い人からのアドバイス

  • 入力欄とボタンも部品にすると、よりスッキリするかも。

次回

次回はReduxを適用していきたい。

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7