5
3

More than 3 years have passed since last update.

React+TypeScript+unstatedで始めるアプリ開発

Last updated at Posted at 2019-12-29

はじめに

Reactは、Facebookとコミュニティによって開発されているユーザーインターフェース構築のためのJavaScriptライブラリです。大体の人は、JavaScriptでReactを書くと思いますが、ReactとTypeScriptの相性が非常に良いので、ぜひTypeScriptでReactを始めてみてはいかがでしょうか?また、Reactで開発を進めていく中で、もっとも煩わしくなるのが状態(state)管理です。これを解消するために、ReduxやUnduxを使うのですが、正直難しいです笑。unstatedを使えば、比較的簡単に状態管理ができると聞いたので、今回は、unstatedを使ってみたいと思います。

開発環境の構築

nodeのインストール

こちらのページから、推奨版をインストールしてください。macの人はnodebrew、Windowsの人はnodistを使うと、nodeのバージョンを簡単に切り替えることができるので、そっちを使ったほうがいいかもしれないです。

create-react-appコマンドのインストール

ターミナル、またはコマンドプロンプトを開いて、以下のコマンドを打ち込んでください。

$ npm install -g create-react-app

アプリの雛形を作る

create-react-appコマンドを使えば一発でアプリの雛形ができる。オプションで--template typescriptをつけることで、TypeScriptを導入できる。

$ create-react-app my-app --template typescript

サーバーを開始する

cdコマンドで、先ほど作ったアプリに移動し、npm startで起動する。

$ cd my-app
$ npm start

http://localhost:3000/ にアクセスして、このような画面が出てきたら成功。

スクリーンショット 2019-12-29 10.30.11.png

カウントアプリを作る

今回は、簡単なカウントアプリを作ってみたいと思います。

コンポーネント(部品)作り

今回は、カウントを表示するコンポーネント(Display.tsx)とカウントを増やすボタン(Button.tsx)の二つを作りたいと思います。src直下に、componentsフォルダを作り、その中にDisplay.tsxButton.tsxを作ります。

src-
   |-components
         |-Display.tsx
         |-Button.tsx
Display.tsx
import React from 'react'

const Display: React.SFC = () => {
    return (
        <div>
            <h1>0</h1>
        </div>
    )
}

export default Display
Button.tsx
import React from 'react'

const Button: React.SFC = () => {
    return (
        <div>
            <button>add!</button>
        </div>
    )
}

export default Button
App.tsx
import React from 'react';
import Display from './components/Display';
import Button from './components/Button';

const App: React.FC = () => {
  return (
    <div>
      <Display />
      <Button />
    </div>
  );
}

export default App;

unstatedの導入

unstatedは、コンポーネントの状態(state)の部分と見た目の部分を引き剥がすだけです。なので、簡単に導入できます。
従来のコンポーネントは、一つのファイルで、状態(state)の管理と見た目の作成を全てを担っていました。

スクリーンショット 2019-12-29 11.11.41.png

これだと、状態を他のコンポーネントに再利用できなくて、どうしても他のコンポーネントに状態を渡したいときは、props経由で状態(state)を渡します。ただ、コンポーネントの構造が複雑になってくると、propsで状態を渡すのがだるくなってきます。しかも、propsは親から子には渡せますが、子から親には渡せないので、開発を進めていると途中で詰むことがあります。

スクリーンショット 2019-12-29 11.20.26.png

一方で、unstatedは、見た目の部分と状態の部分に分けます。状態の部分を、コンテナと呼びます。

スクリーンショット 2019-12-29 11.30.06.png

unstatedは、親子関係なしに状態(state)を渡すことができます。

スクリーンショット 2019-12-29 11.27.40.png

では、実際にunstatedを導入してみます。

$ npm install unstated
$ npm install

unstatedを使うためには、Providerで囲む必要があります

App.tsx
import React from 'react'
import Display from './components/Display'
import Button from './components/Button'
import { Provider } from 'unstated'

const App: React.FC = () => {
  return (
    <Provider>
      <div>
        <Display />
        <Button />
      </div>
    </Provider>
  );
}

export default App;

containerを作ります。src直下にcontainersフォルダを作り、その中にCountContainer.tsを作ります。

src-
   |-containers
   |     |-CountContainer.ts
   |
   |-components
         |-Display.tsx
         |-Button.tsx
CountContainer.ts
import { Container } from 'unstated'

interface IState {
    count: number
}

export default class CountContainer extends Container<IState> {
    public constructor() {
        super()
        this.state = {
            count: 0
        }
        this.addCount = this.addCount.bind(this)
    }

    public addCount() {
        this.setState({
            count: this.state.count + 1
        })
    }
}

containerにあるstateをDisplay.tsxに渡します。

Display.tsx
import React from 'react'
import { Subscribe } from 'unstated'
import CountContainer from '../containers/CountContainer';

const Display: React.SFC = () => (
    <Subscribe to={[CountContainer]}>
        {(cCount: CountContainer) => {
            return (
                <div>
                    <h1>{cCount.state.count}</h1>
                </div>
            )
        }}
    </Subscribe>
)

export default Display

containerにあるaddCountという関数をButton.tsxに渡します。

Button.tsx
import React from 'react'
import { Subscribe } from 'unstated'
import CountContainer from '../containers/CountContainer';

const Button: React.SFC = () => (
    <Subscribe to={[CountContainer]}>
        {(cCount: CountContainer) => {
            return (
                <div>
                    <button onClick={cCount.addCount}>add!</button>
                </div>
            )
        }}
    </Subscribe>
)

export default Button

addボタンを押すと、カウントが増えていきます。

react.gif

5
3
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
3