25
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

create-react-appを使ったTypeScriptのチュートリアル

Posted at

Reactにまだ慣れていない、TypeScriptを今からはじめて触れる人向けに、簡単なチュートリアルを書きます。
この記事の他にもTypeScriptのチュートリアル記事はいくつかありますので、そちらも参考にどうぞ

TypeScriptチュートリアル① -環境構築編-
TypeScript チュートリアル

今回はReduxや、Sagaなどのミドルウェアは一切使わずにとてもシンプルなアプリケーションを作ります。

環境構築

create-react-appを使えばReactの環境構築は簡単にできます。
https://github.com/facebook/create-react-app

今回はTypeScriptを使うので下記のようにコマンドを入力します

npx create-react-app sample-app --typescript

上のコマンドのsample-appの部分がフォルダ名になります。
create-react-appで作成したフォルダに移動してアプリケーションを起動します

cd sample-app/
npm start

これでとりあえず初期画面が表示されました。簡単。
スクリーンショット 2019-07-19 15.53.45.png

コンポーネントを編集してみる

最初に表示されている画面のコードはsrc/App.tsxに記載されています。

App.tsx
import React from "react";
import logo from "./logo.svg";
import "./App.css";

const App: React.FC = () => {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
};

export default App;

Reactの開発は基本的にsrcフォルダ内に書いていきます。
まずはこのApp.tsxをもっとシンプルなものに書き換えます。

App.tsx
import React from "react";

class App extends React.Component {
  render() {
    return <p>Hello world</p>;
  }
}

export default App;
スクリーンショット 2019-07-19 16.11.47.png

Hello worldが表示されるだけのシンプルな画面になりました。

別のコンポーネントを作成してApp.tsxにimportしてみます。

Sample.tsx
import React from "react";

class Sample extends React.Component {
  render() {
    return <p>2つ目のコンポーネント</p>;
  }
}

export default Sample;
App.tsx
import React from "react";
import Sample from './Sample'

class App extends React.Component {
  render() {
    return (
      <p>Hello world</p>
      <Sample/>
    );
  }
}

export default App;

これで立ち上げてみます。

Failed to compile.

./src/App.tsx
  Line 9:  Parsing error: JSX expressions must have one parent element

エラーになりますね。
エラー内容の通り、jsxでは一つの親要素が必要となります。
<React.Fragment>で全ての要素を囲むことでこのエラーを回避できます。

App.tsx
import React from "react";
import Sample from "./Sample";

class App extends React.Component {
  render() {
    return (
      <React.Fragment>
        <p>Hello world</p>
        <Sample />
      </React.Fragment>
    );
  }
}

export default App;

これで問題なく画面が表示されました。
スクリーンショット 2019-07-19 16.22.18.png

Propsを使ってみる

ReactにはPropsとStateという2つの変数が存在します。
ふたつの変数の違いについてはこちらの記事をどうぞ。
React における State と Props の違い
今からはじめるReact.js〜propsとstate、それからrefs〜

先程作成したSample.tsxにApp.tsxから変数を渡してみましょう。

App.tsx
import React from "react";
import Sample from "./Sample";

class App extends React.Component {
  render() {
    return (
      <React.Fragment>
        <p>Hello world</p>
        <Sample num={"5"} />
      </React.Fragment>
    );
  }
}

export default App;

ここではnumという変数に"5"という文字列を代入しています。

Sample.tsx
import React from "react";

class Sample extends React.Component {
  render() {
    return <p>{this.props.num}つ目のコンポーネント</p>;
  }
}

export default Sample;

またエラーになりました。

Type '{ num: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Sample> & Readonly<{}> & Readonly<{ children?: ReactNode; }>'.
  Property 'num' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Sample> & Readonly<{}> & Readonly<{ children?: ReactNode; }>'.  TS2322

     7 |       <React.Fragment>
     8 |         <p>Hello world</p>
  >  9 |         <Sample num={"5"} />
       |          ^
    10 |       </React.Fragment>
    11 |     );
    12 |   }

Typescriptでは型をちゃんと指定してあげなければなりません。
Sample.tsxを以下のように書き換えてみましょう。

Sample.tsx
import React from "react";

interface Props {
  num: string;
}

class Sample extends React.Component<Props> {
  render() {
    return <p>{this.props.num}つ目のコンポーネント</p>;
  }
}

export default Sample;

これで変数numがstring型であることを定義できました。
エラーも解消され、問題なく画面が表示されます。
スクリーンショット 2019-07-19 16.33.42.png

Stateを使ってみる

App.tsxを書き換えて、Stateを使って何かしら値を画面に出力してみます。
スクリーンショット 2019-07-19 16.45.26.png
スクリーンショット 2019-07-19 16.45.45.png
ボタンを押下されたら文言が変わるという単純な実装をしてみました。
JavaScriptを使ったReactならこのように書くと思います。

App.tsx
import React from "react";
import Sample from "./Sample";

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "最初のメッセージ"
    };

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({
      message: "ボタンが押されました"
    });
  }

  render() {
    return (
      <React.Fragment>
        <p>Hello world</p>
        <Sample num={"5"} />

        <p>{this.state.message}</p>
        <button onClick={this.handleClick}>ボタン</button>
      </React.Fragment>
    );
  }
}

export default App;

しかしこれではエラーになってしまいますね。
Propsのときと同様に、TypeScriptでは型の指定が必要です。
下記のように書き換えましょう。

App.tsx
import React from "react";
import Sample from "./Sample";

interface Props {}

interface State {
  message: string;
}

class App extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);

    this.state = {
      message: "最初のメッセージ"
    };

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({
      message: "ボタンが押されました"
    });
  }

  render() {
    return (
      <React.Fragment>
        <p>Hello world</p>
        <Sample num={"5"} />

        <p>{this.state.message}</p>
        <button onClick={this.handleClick}>ボタン</button>
      </React.Fragment>
    );
  }
}

export default App;

これで問題なく画面が表示されました。

参考

TypeScriptチュートリアル① -環境構築編-
TypeScript チュートリアル
React における State と Props の違い
今からはじめるReact.js〜propsとstate、それからrefs〜

25
21
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
25
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?