Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.
  • ほぼ参考にしました

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だけで結構十分かなぁと思ったりもしました.🤔そこは規模感だったりいろいろと考えていきたいです.😊

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした