Redux学習まとめ

10492 ワード

参考阮一峰ブログ:reduxチュートリアル

一、react設計思想

  • webアプリケーションはステータスマシンであり、ビューはステータスに対応しています.
  • すべてのステータスは、1つのオブジェクトに保存されます.

  • 二、redux基本概念


    1. Store


    Storeはデータを保存する場所であり、1つのコンテナと見なすことができ、アプリケーション全体に1つのStoreしかない.

    2. State


    StateはStoreオブジェクトのある時点のデータ集合であり、現在時刻のStateはstoreを通過することができる.getState()を取得します.

    3. Action


    StateとViewは1つ1つ対応しており、ActionはViewからの通知であり、Stateが変化するはずであることを示している.Actionはオブジェクトで、typeプロパティが必要で、Actionの名前を表します.
    注:Stateを変更する唯一の方法はActionを使用することです.

    4. Action Creator


    関数を定義してアクションを生成するために使用されます
    const ADD_TODO = '  TODO';
    function addTodo(text) {
      return {
        type: ADD_TODO,
        text
      }
    }
    const action = addTodo('Learn Redux');

    5. store.dispatch()


    ビューがアクションを発行する唯一の方法であり、アクションオブジェクトをパラメータとして受け入れて送信します.
    import { createStore } from 'redux';
    const store = createStore(fn);
    store.dispatch({
      type: 'ADD_TODO',
      payload: 'Learn Redux'
    });

    6. Reducer


    Reducerは、Actionと現在のStateをパラメータとして受け入れ、新しいStateを返す関数です.
    const defaultState = 0;
    const reducer = (state = defaultState, action) => {
      switch (action.type) {
        case 'ADD':
          return state + action.payload;
        default: 
          return state;
      }
    };
    const state = reducer(1, {
      type: 'ADD',
      payload: 2
    });

    注意:実際の応用ではstore.dispatchメソッドはReducerの自動実行をトリガーするので、createStoreはReducerをパラメータとして新しいStoreを生成することを受け入れることができる.

    7.純関数


    Reducer関数の最も重要な特徴は,同じ入力で必ず同じ出力が得られる純粋な関数である.純粋な関数は関数式プログラミングの概念であり、以下の制約を守らなければならない.
    1.  
    2.  I/O API
    3.  Date.now() Math.random() , 

    注意:Reducer関数ではStateを変更することはできません.新しいオブジェクトを返さなければなりません.
    // State  
    function reducer(state, action) {
      return Object.assign({}, state, { thingToChange });
      //  
      return { ...state, ...newState };
    }
    // State  
    function reducer(state, action) {
      return [...state, newItem];
    }

    8. store.subscribe()


    Storeはstoreを使用できます.subscribeメソッドは傍受関数を設定し,Stateが変化すると自動的にこの関数を実行する.
    // View listen View 
    import { createStore } from 'redux';
    const store = createStore(reducer);
    store.subscribe(listener);
    //store.subscribe , listener 
    let unsubscribe = store.subscribe(() =>
      console.log(store.getState())
    );
    unsubscribe();

    三、Storeの実現


    storeは3つの方法を提供した:store.getState()/store.dispatch()/store.subscribe()
    import { createStore } from 'redux';
    let { subscribe, dispatch, getState } = createStore(reducer);

    注意:createStoreメソッドでは、stateの最初の状態を示す2番目のパラメータも受け入れられます.Reducer関数のデフォルトの初期値を上書きします.
    //createStore 
    const createStore = (reducer) => {
      let state;
      let listeners = [];
      const getState = () => state;
      const dispatch = (action) => {
        state = reducer(state, action);
        listeners.forEach(listener => listener());
      };
      const subscribe = (listener) => {
        listeners.push(listener);
        return () => {
          listeners = listeners.filter(l => l !== listener);
        }
      };
      dispatch({});
      return { getState, dispatch, subscribe };
    };

    四、Reducerの分割


    Reduxは、Reducerの分割のためのcombineReducers法を提供する.
    import { combineReducers } from 'redux';
    
    const chatReducer = combineReducers({
      chatLog,
      statusMessage,
      userName
    })
    export default todoApp;

    注意:state属性名はサブReducerと同じ名前でなければなりません.combineReducers()関数は、Stateのkeyに基づいて対応するサブReducerを実行し、戻り結果を大きなstateオブジェクトにマージします.
    //combineReducer 
    const combineReducers = reducers => {
      return (state = {}, action) => {
        return Object.keys(reducers).reduce(
          (nextState, key) => {
            nextState[key] = reducers[key](state[key], action);
            return nextState;
          },
          {} 
        );
      };
    };

    五、仕事の流れ

  • ユーザがActionを発行する.store.dispatch(action);
  • StoreはReducerを自動的に呼び出し、現在のStateと受信したActionの2つのパラメータを入力し、Reducerは新しいStateを返す.let nextState = todoApp(previousState, action);
  • Stateが変化すると、Storeはリスニング関数を呼び出す.store.subscribe(listener);
  • listenerはstoreを通過した.getState()は現在の状態を取得する、reactを使用すると、Viewの再レンダリングがトリガーされる.
  • function listerner() {
      let newState = store.getState();
      component.setState(newState);   
    }

    六、例:カウンタ機能:カウンタに増減のActionを追加し、パラメータvalueの値をWebページに表示します.Storeのリスニング関数はrenderに設定され、Stateの変化のたびにWebページが再レンダリングされます.
    const Counter = ({ value, onIncrement, onDecrement }) => (
      

    {value}

    ); const reducer = (state = 0, action) => { switch (action.type) { case 'INCREMENT': return state + 1; case 'DECREMENT': return state - 1; default: return state; } }; const store = createStore(reducer); const render = () => { ReactDOM.render( () => store.dispatch({type: 'INCREMENT'})} onDecrement={() => store.dispatch({type: 'DECREMENT'})} />, document.getElementById('root') ); }; render(); store.subscribe(render);