LoginSignup
11
12

More than 3 years have passed since last update.

React + TypeScript + MobXで簡易Counterアプリで素振りを行った

Last updated at Posted at 2018-04-04
  • ほぼ参考にしました

sample-react-mobx

プロジェクト作成

今回はTypeScriptを利用するので,optionをつけてアプリを作成します

create-react-app --scripts-version=react-scripts-ts [app_name]

mobxをインストール

npm install --save mobx mobx-react

いじっていく

まずApp.tsxを以下のように変更します.

App.tsx
import React, { Component } from 'react';
import CountContainer from './containers/CountContainer';

class App extends Component {
  render() {
    return (
      <CountContainer />
    );
  }
}

export default App;

今回,stateをもらってくる役目をCountContainerにしてもらいました.
(reduxっぽい感じにしたかった・・・)

必要なディレクトリを作成

mkdir containers
mkdir components
mkdir stores

storeはデータの置き場みたいなもので,このstoreのメソッドを呼び出すことによってデータを変更していきます.

CountContainer

./containers/CountContainer.tsx
import React, { Component } from 'react';
import { Provider } from 'mobx-react';
import CountStore from '../store/CountStore';
import Counter from '../components/Counter';

// create store
const stores = new CountStore();

export default class CountContainer extends Component {
    render() {
        return (
            <Provider count={stores}>
                <Counter />
            </Provider>
        );
    }
}

Counter

./components/Counter.tsx
import React, { Component } from 'react';
import { inject, observer } from 'mobx-react';
import { CountStoreType } from '../store/CountStore';

type Props = {
    count?: CountStoreType
};

@inject('count')
@observer
class Counter extends Component<Props> {
    render() {
        const { count } = this.props;

        return (
            <div>
                Counter : {count!.num} <br />
                < button onClick={count!.onIncrement} > + </button>
                < button onClick={count!.onDecrement} > - </button>
                < br /> GetDoubleCount: {count!.getDoubleCount}
            </div>
        );
    }
}

export default Counter;

CountStore

Typeを無理やり作ってますが,こんな感じの定義で

./store/CountStore.ts
import { observable, action, computed } from 'mobx';

export type CountStoreType = {
  num: number
  getDoubleCount: () => void
  onIncrement: () => void
  onDecrement: () => void
};

export default class CountStore {
  @observable num = 0;

  @computed get getDoubleCount() {
    return this.num * 2;
  }

  @action.bound onIncrement() {
    this.num = this.num + 1;
  }

  @action.bound onDecrement() {
    this.num = this.num - 1;
  }
}

あとはyarn startで動くと思います.

詰まった点

import fails with 'no default export'

tsconfig.json"compilerOptions"の中に以下を記述します.

"allowSyntheticDefaultImports": true

Providerで値を渡す

このブログに書かれているようにProviderからもらってくる値には?を付ける必要があります.

アノテーション周り

"experimentalDecorators": true,

これをtsconfig.jsonに書くとエラーが消えました.

まとめ

今回はMobX, TypeScriptの素振りがしたくて少し触ってみました.コードを組んでいく方向性としてcontainerを用意しましたが,componentとstoreだけで結構十分かなぁと思ったりもしました.🤔そこは規模感だったりいろいろと考えていきたいです.😊

11
12
1

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
11
12