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
コンポーネントを編集してみる
最初に表示されている画面のコードはsrc/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
をもっとシンプルなものに書き換えます。
import React from "react";
class App extends React.Component {
render() {
return <p>Hello world</p>;
}
}
export default App;

Hello worldが表示されるだけのシンプルな画面になりました。
別のコンポーネントを作成してApp.tsxにimportしてみます。
import React from "react";
class Sample extends React.Component {
render() {
return <p>2つ目のコンポーネント</p>;
}
}
export default Sample;
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>
で全ての要素を囲むことでこのエラーを回避できます。
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;
Propsを使ってみる
ReactにはPropsとStateという2つの変数が存在します。
ふたつの変数の違いについてはこちらの記事をどうぞ。
React における State と Props の違い
今からはじめるReact.js〜propsとstate、それからrefs〜
先程作成したSample.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"という文字列を代入しています。
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を以下のように書き換えてみましょう。
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型であることを定義できました。
エラーも解消され、問題なく画面が表示されます。
Stateを使ってみる
App.tsxを書き換えて、Stateを使って何かしら値を画面に出力してみます。
ボタンを押下されたら文言が変わるという単純な実装をしてみました。
JavaScriptを使ったReactならこのように書くと思います。
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では型の指定が必要です。
下記のように書き換えましょう。
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〜