LoginSignup
2
4

More than 3 years have passed since last update.

模写で"なんとなく"理解する React-Redux超基礎

Last updated at Posted at 2019-05-03

理論そっちのけで、とりあえず簡単なアプリを作ってみます。

今回作るもの

なんてことのない、ただのカウントアプリです↓

giphy.gif

注意点

ただ模写していく事で「あ、なんとなく書けるかも」と思えることが目的です。
理論などの説明は下記リンク群が大変参考になりました。

全くつかめていない方は、これらを見てから書いてみるとわかりやすいと思います。

開発環境

カテゴリ バージョン   
OS macOS Mojave 10.14.4
Node.js 10.15.3
Yarn 1.13.0
React 16.8.6
Redux 4.0.1

模写の準備

開発環境の構築

Node.js, Yarnのインストール

ここの説明は省略します。
わからない人は、このQiitaが懇切丁寧です。

create-react-appのインストール

Facebook社が作ってくださった「create-react-app」という雛形をダウンロードします。

$ yarn global add create-react-app

※"./path/to/applciation"の部分で作成するアプリケーションへのパスを指定
$ create-react-app ./path/to/application

このような、React自身やその他諸々のライブラリをまとめて、雛形を作成してくれるツールを「boilerplate」と言います。

色々な種類がありますので、気になる方はこちらを参考に。

実際に雛形が作成され、下記のようなフォルダ・ファイル群が生成されます↓

.
├── README.md
├── node_modules
├── package.json
├── public
├── src
└── yarn.lock

とりあえず起動してみましょう。Reactのロゴがブラウザで表示されれば成功です。

$ yarn start

Redux, react-reduxのインストール

ちなみにreact-reduxはReactとReduxの仲介役を担っているモジュールです。

$ yarn add redux react-redux

これで開発環境は構築できました。

ファイル構成を整える

srcディレクトリの配下をこんな感じにしておきましょう。
あらかじめフォルダやファイルを作っていくことで、模写がラクになります。

├── App.css
├── App.test.js
├── actions
│   └── index.js
├── components
│   └── App.js
├── index.js
├── reducers
│   ├── count.js
│   └── index.js
└── serviceWorker.js

レッツ模写!

Actionの定義

storeにメッセージを送るためのActionを定義します。

カウントアプリは「+」と「-」ボタンによって状態を変化させるだけですので、必要なアクションは2つのみとなります。

acitons/index.js
export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'

// 書き方が2通りありますが、どちらでも問題ないです
export const increment = () => {
  return {
    type: INCREMENT
  }
}

export const decrement = () => ({
  type: DECREMENT
)}

Reducerの実装

storeから送られた情報をもとにstateを実際に変更する「Reducer」を実装しましょう。

index.jsの実装

Reducer群を管理するindex.jsを実装します。

今回作成するアプリは1つのReducerしか持たないので、count.jsと分離する必要はありません。
ただ、規模の大きいアプリの場合は必要となりますので、今後の為にもやっておきましょう。

reducers/index.js
import { combineReducers } from 'redux'
import count from './count'

export default combineReducers(({ count }))

count.jsの実装

カウンターの数字を変更する部分となります。
storeから送られる情報の中のaction.typeによって、数字を増やすのか・減らすのかを決めています。

reducers/count.js
import { INCREMENT, DECREMENT } from '../actions'

//コンポーネントの初期値を設定
const initialState = { value: 0 }

export default (state = initialState, action) => {
  switch (action.type) {
    case INCREMENT:
      return { value: state.value + 1 }
    case DECREMENT:
      return { value: state.value - 1 }
    default:
      return state
  }
}

storeの実装

実装されたReducerをもとに、storeを作成します。

index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'

import reducer from './reducers'
import App from './components'
import * as serviceWorker from './serviceWorker'

// 作成されたReducerをもとにstoreを作成
// アプリケーション内部の全てのstateは、このstateに集約される
const store = createStore(reducer)

// Providerによって、storeがどのコンポーネントからも参照できるようになる
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

serviceWorker.unregister();

コンポーネントの実装

index.jsで呼び出している「App」コンポーネントを実装しましょう。

components/App.js
import React, { Component } from 'react'
import { connect } from 'react-redux'

import { increment, decrement } from '../actions'

class App extends Component {
  render() {
    const props = this.props
    return (
      <React.Fragment>
        <div>count:{props.value}</div>
        <button onClick={props.increment}>+</button>
        <button onClick={props.decrement}>-</button>
      </React.Fragment>
    );
  }
}

// stateから必要な情報をコンポーネントにマッピングする関数
const mapStateToProps = state => ({ value: state.count.value })

// dispatch関数をコンポーネントにマッピングする関数
const mapDispatchToProps = dispatch => ({
  increment: () => dispatch(increment()),
  decrement: () => dispatch(decrement())
})

// こんな書き方もある↓
// const mapDispatchToProps = ({ increment, decrement })

// stateとacitonをコンポーネントに関連づける
export default connect(mapStateToProps, mapDispatchToProps)(App)

次は...

TODOリストや、Ajax通信を実装してみるといいかもしれません。

2
4
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
2
4