LoginSignup
0
1

More than 3 years have passed since last update.

基礎からのRedux

Posted at

Reduxの基礎を理解するためのメモ.
参照:Redux入門【ダイジェスト版】10分で理解するReduxの基礎

Reduxの概念とデータフローについて学ぶ

Reduxとは

アプリケーションを作成する際,DB上のデータをpropsでバケツリレーのように受け渡しするのは非効率.加えて,親コンポーネントのstateに子コンポーネントが影響する構造は,全体のstateを把握するのが困難となり,不具合の原因となる.

この問題を解決するのが,ReactJSが扱うUIのstate管理のためのフレームワークであるReduxである.Reduxを用いることでアプリケーション全体(App.js)の状態を管理し,更新,描画することが容易になる.

Reduxの要素

  1. ActionCreatorメソッド
  2. Actionオブジェクト
  3. Store
  4. State
  5. Reducerメソッド

これらの要素が機能することでアプリケーション全体のデータを操作することが可能となる.

Reduxのフロー

ToDoアプリを例に説明する.
ユーザがtodoのテキストを入力して追加ボタンを押した場合を考える.

ActionCreatorメソッド

このとき入力されたテキストがActionCreatorメソッドに渡される.

todo.js
function addTodo(text) {
  return {
    type: ADD_TODO,
    text: `${text}`
  }
}

Actionオブジェクト

Actionオブジェクトは,「何をする」という情報をtypeプロパティに持つ.このActionオブジェクトが,ActionCreatorメソッドにより作成される.

todo.js
{
  type: 'ADD_TODO',
  text: 'Build my first Redux app'
}

dispatch

dispatch文によって,ActionCreatorメソッドによって作成されたActionオブジェクトがStoreに渡される.

todo.js
dispatch(addTodo(text))

Store

Storeは,アプリケーションの状態(state)を保持している場所.
index.jsに作成され,そこでreducerが適応される.

Storeは,dispatchされると,引数のactionと現在保持するStateを,Reducerへと渡し,新しいStateを作成する.

index.js
import { createStore } from 'redux'
import reducer from './reducer'

//Storeの作成とreducerの適応
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const thunkWithClient = thunk.withExtraArgument(client)
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunkWithClient)))
reducer.js
import { combineReducers } from 'redux'
import todoApp from './reducers'

State

アプリケーションでの状態.
下記の例では,「現在表示されている表示/非表示」,「todoリスト」をstateとして保持.

{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}

reducerメソッド

reducerメソッドは,actionとstateから新しいstateを作成して返すメソッド.

reducerの実装は,actionのtypeに応じて処理を書く.

todo.js
function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case COMPLETE_TODO:
      return [
        ...state.slice(0, action.index),
        Object.assign({}, state[action.index], {
          completed: true
        }),
        ...state.slice(action.index + 1)
      ]
    default:
      return state
  }
}

function visibilityFilter(state = SHOW_ALL, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return action.filter
    default:
      return state
  }
}

function todoApp(state = {}, action) {
  return {
    visibilityFilter: visibilityFilter(state.visibilityFilter, action),
    todos: todos(state.todos, action)
  }
}

アプリケーション全体で見てみると...

App.js/render()

初回はinitialStateを用いてレンダリング

App.js/componentDidMount()

/ActionCreator()呼び出し

todo.js/ActionCreator()

/dispatch

reducers.js

todo.js/reducer

App.jsのstate更新

App.js/render()

0
1
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
0
1