何かやってみるブログ

興味をもったこと、趣味のこと、技術について色々書きます。

Redux入門してみた

Redux Tutorialをやろうとしたのですが、ちょっとレベルが高く理解しにくと思ったので最小限のカウントアプリを作りながらReduxについて自分なりにまとめてみました。

用語の整理

redux

アプリケーションの状態を管理するためのオープンソースのJavaScriptライブラリ。

react-redux

reduxとreactをつないでくれる便利なやつ。

store

stateの値を保持するオブジェクトのこと。

reducer

actionのtypeをトリガーにしてstateを返す関数のこと。

action

reducerにstateがどのように変わるのかを伝えるオブジェクトのこと。 必ず、typeというkeyを持つ。

Provider

storeを参照できるようにしてくれるやつ

react-redux.js.org

connect

ReactコンポーネントをRedux storeに繋いでくれるやつ

react-redux.js.org

試す

以下の環境で試しました。

node  v12.18.0
react  16.13.1
redux 4.0.5
react-redux 7.2.0

プロジェクトを作成する

create-react-appで作っていきます。

$ create-react-app my-app

create-react-app が入っていない場合は、インストールが必要です。

$ yarn add global create-react-app

起動する

$ yarn start

スタート画面が表示されればOKです。

f:id:s-takaya1027:20200619001025p:plain

パッケージを追加する

$  yarn add redux react-redux

適当にカウントアプリのUIを作る

import React from 'react';
import logo from './logo.svg';
import './App.css';

const  App = () => {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <h1>0</h1>
        <button>+</button>
        <button>-</button>
      </header>
    </div>
  );
}

export default App;

f:id:s-takaya1027:20200619004030p:plain

actionを作る

$ mkdir src/actions 
$ mkdir touch src/actions/index.js
const INCREMENT = "INCREMENT"
const DECREMENT = "DECREMENT"

export const increment = () => ({
   type: INCREMENT
})

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

reducerを作る

$ mkdir src/reducers
$ touch src/reducers/index.js
import { INCREMENT, DECREMENT } from "../actions"

const initializeCount = { count: 0 };

const Counter = (state = initializeCount, action) => {
  switch(action.type){
    case INCREMENT:
      return { count: state.count + 1}
    case DECREMENT:
      return { count: state.count - 1}
    default:
      return state
  }
}

export default Counter

storeを作る

//以下を追加
import { createStore } from 'redux'
import Counter from "../src/reducers"
const store = createStore(Counter,  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

createStoreの第二引数にReduxのデバックツールを使う設定を追加しています。

github.com

良い感じにチェックできます。

f:id:s-takaya1027:20200619014212p:plain

ReactとReduxを繋ぐ

ProviderでAppを囲む

import { Provider } from 'react-redux'
・
・
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

connectを使って繋ぐ

・
・
import { increment, decrement } from "../src/actions"
import { connect } from "react-redux"


const  App = props => {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
         <h1>{props.count}</h1>
        <button onClick={props.increment}>+</button>
        <button onClick={props.decrement}>-</button>
      </header>
    </div>
  );
}

const mapStateToProps = (state) => {
  return {
    count: state.count
  }
}

const mapDispatchToProps = { increment, decrement }

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App)

動作確認

動作を確認することができました。

f:id:s-takaya1027:20200619014922p:plain