Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
12
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@mitubaEX328

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

  • ほぼ参考にしました

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
12
Help us understand the problem. What are the problem?