Redux学習ノート-Vol.2-基礎

8746 ワード

基礎
アクション
アクションは、アプリケーションからstoreにデータを伝えるペイロードです.それはstoreデータの唯一のソースです.普通はstore.dispatch()を通じてactionをstoreに伝えます.くりを一つあげる:
const ADD_TODO = 'ADD_TODO';

//  action     :
{
    type: ADD_TODO,
    text: 'Build my first Redux app'
}
はっきり言って、actionは普通のjavascriptオブジェクトですが、このactionを表すオブジェクトにはtypeフィールドが必要で、実行する動作を表すことに注意してください.できるだけactionでデータを送ることを減らす.
アクションクリエーター
アクションクリエーターはactionを生成する方法です.
function addTodo(text){
    return {
        type: 'ADD_TODO',
        text
    }
}
Reduxでは、action creatorの結果をdispatch()に返すだけで、dispatchプロセスを開始することができます.
dispatch(addTodo(text));
または、結合されたaction creatorを作成して、自動的にdispatchを作成します.
const boundAddTodo = (text) => dispatch(addTodo(text));
boundAddTodo();
今まで、actions.jsを書きました.
//action type
export const ADD_TODO = 'ADD_TODO';
export const TOGGLE_TODO = 'TOGGLE_TODO';
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER';


//    
export const VisibilityFilters = {
    SHOW_ALL: 'SHOW_ALL',
    SHOW_COMPLETED: 'SHOW_COMPLETED',
    SHOW_ACTIVE: 'SHOW_ACTIVE'
};


//action creator
export function addTodo(text){
    return {
        type: ADD_TODO,
        text
    }
}

export function toggleTodo(index){
    return {
        type: TOGGLE_TODO,
        index
    }
}

export function setVisibilityFilter(filter){
    return {
        type: SET_VISIBILITY_FILTER,
        filter
    }
}
Reducer
actionがあったら、reducerがどのようにstateを更新するかを指定します.
State構造
明確な点は、Reduxアプリケーションでは、すべてのstateが単一のオブジェクトに保存されていることである.くりを一つあげるには、一つのtodoアプリケーションで、二つの異なるデータを保存する必要があります.
  • 現在選択されているタスクフィルタ条件
  • 完全なタスクリスト
  • {
        visiibilityFilter: 'SHOW_ALL',
        todos: [
            {
                text: 'Consider using Redux',
                complete: true
            },
            {
                text: 'Keep all state in a single tree',
                complete: false
            }
        ]
    }
    
    actionを処理する
    Reducerは純粋な関数で、古いstateとactionを受け入れて、新しいstateに戻ります.
        (previousState, action) => newState
    
    reducerの純粋さを保つことは非常に重要です.いつまでもreducerでこれらの操作をしないでください.
  • 入力パラメータを変更する
  • は、API要求およびルーティング・ホッピング
  • のような、副作用がある動作を実行する.
  • は、Date.now()またはMath.random()
  • のような非純粋な関数を呼び出します.
    純粋なレデューサーはどんなものですか?入ってきたパラメータが同じであれば、計算された次のstateに戻るのは同じである.はい、reducerを書き始めます.
    import { VisibilityFilters } from './actions';
    
    const initialState = {
        visibilityFilter: VisibilityFilter.SHOW_ALL,
        todo: []
    };
    
    function todoApp(state = initialState, action){
        switch (action.type){
            case SET_VISIBILITY_FILTER:
                return  Object.assign({}, state, {
                    visibilityFilter: action.filter
                });
            default:
                return state;
        }
    }
    
    注意:
  • stateを修正しないでください.上のコードはObject.assign()を使用してコピーを作成しただけです.
  • は、defaultの場合、古いstateに戻る.未知の場合は、必ず古いstateに戻ります!
  • 複数のアクションを扱う
    まず、2つのADD_TODOTOGGLE_TODOを追加します.
    case ADD_TODO:
        return Object.assign({}, state, {
            todos: [
                ...state.todos,//ES6   
                {
                    text: action.text,
                    complete: false
                }
            ]
        });
        
    case TOGGLE_TODO:
        return Object.assign({}, state, {
            todos: state.todos.map(function(todo, index){
                if (index === action.index){
                    return Object.assign({}, todo, {
                        completed: !todo.completed;
                    });
                }
                return todo;
            });
        });
    
    分割reducer
    function todos(state = [], action){
        switch(action.type){
            case ADD_TODO:
                return [
                    ...state,
                    {
                        text: action.text,
                        completed: false
                    }
                ];
            case TOGGLE_TODO:
                return state.map(function(todo, index){
                    if (index === action.index){
                        return Object.assign({}, todo, {
                            completed: !todo.completed
                        });
                    }
                    return todo;
                });
        }
    }
    
    function todoApp(state = initialState, action){
        switch(action.type){
            case SET_VISIBILITY_FILTER:
                return Object.assign({}, state, {
                    visibilityFilter: action.filter
                });
            case ADD_TODO:
            case TOGGLE_TODO:
                return Object.assign({}, state, {
                    todos: todos(state.todos, action)
                });
            default:
                return state;
        }
    }
    
    Todosはまだstateを受け入れていますが、ここのstateは配列になりました.todoAppは更新するべき部分だけをtodosに伝えます.これがreducer合成であり,Reduxアプリケーションを開発するための最も基本的なモデルである.visibility Filterを同じ方法で分割します.
    function visibilityFilter(state = SHOW_ALL, action){
        switch(action.type){
            case SET_VISIBILITY_FILTER:
                return action.filter;
            default:
                return state;
        }
    }
    
    然と修正総のreducer
    function todoApp(state = {}, action){
        return {
            visibilityFilter: visibilityFilter(state.visibilityFilter, action),
            todos: todos(state.todos, action)
        };
    }
    
    合併のことはReduxに任せます.
    import { combineReducers } from 'redux';
    
    const todoApp = combineReducers({
        visibilityFilter,
        todos
    });
    
    export default todoApp;
    
    ES 6大法好combineReducersが受け取ったのはオブジェクトで、関数を返します.これにより、すべてのトップレベルのreducerを独立ファイルに置くことができ、各reducer関数をexportで暴露し、その後、import * as reducerでkeyとしてのObjectを導入することができる.
    import { combineReducers } from 'redux';
    import * as reducer from './reducers';
    
    const todoApp = combineReducers(reducer);
    //ES6   !
    
    現在までに、私達は完全なreducers.js↓を得ました.
    import { combineReducers } from 'redux';
    import { ADD_TODO, TOGGLE_TODO, SET_VISIBILITY_FILTER, VisibilityFilters } from './actions';
    
    function visibilityFilters(state = SHOW_ALL, action){
        switch(action.type){
            case SET_VISIBILITY_FILTER:
                return action.filter;
            default:
                return state;
        }
    }
    
    function todos(state = [], action){
        switch(action.type){
            case ADD_TODO:
                return [
                    ...state,
                    {
                        text: action.text,
                        completed: false
                    }
                ];
            case TOGGLE_TODO:
                return state.map(function(todo, index){
                    if (index === action.index){
                        return Object.assign({}, todo, {
                            completed: !todo.completed
                        });
                    }
                    return todo;
                });
            default:
                return state;
        }
    }
    
    const todoApp = combineReducer({
        visibilityFilters,
        todos
    });
    
    export default todoApp;
    
    Store
    Storeを学ぶ前に、actionとreducerを振り返ってみます.
  • アクション:「何があったか」を表すために使われます.
  • Reducer:「何があったか」によって、stateの更新方法を決定します.
  • 今知っておきたいのは、Storeの役割は上記の2つのことです.Storeの役割について:
  • アプリケーションを維持するstate
  • getState()方法でstate
  • を取得する.
  • dispatch(action)はactionを配信するために用いられ、さらにstate
  • を更新する.
  • subscribe(listener)は、reducerを登録し、登録をキャンセルする関数
  • を返します.
    FYI:Reduxは単一のStoreしかありません.ロジックが複雑で分解が必要な場合は、Reducerに手を下してください.Now、すでに書いたreducerに基づいてstoreを作成します.so easuy~
    import { createStore } from 'redux';
    import todoApp from './reducers';
    
    let store = createStore(todoApp);
    
    createStore()メソッドが可能な第二のパラメータはオプションであり、stateの初期状態を設定するために使用されます.
    let store = createStore(todoApp, initialState);
    
    actionsを開始する
    私たちはもうstoreを持っています.どうやって使うかを見てみます.
    import { addTodo, toggleTodo } from './actions';
    
    //  state
    store.getState();
    
    //  (  ),state       ,   
    let unsubscribe = store.subscribe(function(){
        console.log(store.getState());
    });
    
    //  action
    store.dispatch(addTodo('finish your resume.'));
    store.dispatch(toggleTodo(0));
    
    //    state  
    unsubscribe();  
    
    このパーティーを見て何をしましたか?↓
    //     store(  store    !)
    import { createStore } from 'redux';
    import todoApp from './reducers';
    
    let store = createStore(todoApp);
    
    厳格な一方向データストリーム(Reduxコア)
  • 開始:store.dispatch(action).
  • リレー:storeは、開始されたactionと現在のstateをルートreducerに伝達し、ルートreducerはこの2つのパラメータをサブreducer達に伝達する.
  • 更新:子reducer達の各司其職を通過した後、根reducerは彼らの出力を単一のstateツリーに合併します.
  • 保存:storeはこのreducerが戻ってきたstateを保存し、今回のデータストリームは終了します.