redux學習:javascript
1.應用只有一個store,用於保存整個應用的全部的狀態數據信息,即state,一個state對應一個頁面的所需信息java
注意:他只負責保存state,接收action, 從store.dispatch(aciton)得到一個action, 而後要經過reducer整理,舊state和新action,計算出新的statereact
1.1 建立:es6
store = Redux.createStore( reducer, initState)
1.2 方法:編程
store.getState() //獲取當前額state
store.dispatch() //view 執行了某個操做,使用這個函數告訴store,否則store是不知道的
store.subscribe() //用於component 監聽state變化,註冊監聽事件,返回取消監聽的函數
2.Action 一次操做,類型爲對象redux
2.1 api
{
type:‘add_count’, //type屬性爲必須存在 payload:‘something’ //該操做要改變或增長的數據 }
2.2 Action Creater: View 要發送多少種消息,就會有多少種 Action。若是都手寫,會很麻煩。能夠定義一個函數來生成 Action,這個函數就叫 Action Creator。數組
const ADD_TODO = '添加 TODO';
function addTodo(text) { return { type: ADD_TODO, text } } const action = addTodo('Learn Redux');
3.store.dispatch() //view 執行了某個action操做,使用這個函數告訴store,否則store是不知道的dom
import { createStore } from 'redux'; const store = createStore(fn); //既然是告訴store執行了action,參數固然就是action了 store.dispatch({ type: 'ADD_TODO', payload: 'Learn Redux' });
4.Reducer : 函數,接收( state,action)做爲參數,爲store計算出新的state函數式編程
const defaultState = 0; //初始state, 經過es6,傳遞默認值 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 });
4.1 reducer自動執行:
在react中,不須要每次執行了有action以後手動執行 reducer,每一次store從store.dispatch(action),中得到一個action後,都會自動執行reducer,全部咱們只須要告訴store,reducer函數是怎樣的就能夠了
const store = createStore(reducer, initState); //其中initState是store的初始值,如有第二個參數,則忽略reducer中設置的默認值
4.2 純函數
Reducer 函數最重要的特徵是,它是一個純函數。也就是說,只要是一樣的輸入,一定獲得一樣的輸出。
純函數是函數式編程的概念,必須遵照如下一些約束。
不得改寫參數 不能調用系統 I/O 的API 不能調用Date.now()或者Math.random()等不純的方法,由於每次會獲得不同的結果
4.3 因爲 Reducer 是純函數,就能夠保證一樣的State,一定獲得一樣的 View。但也正由於這一點,Reducer 函數裏面不能改變 State,必須返回一個全新的對象,請參考下面的寫法
// State 是一個對象 function reducer(state, action) { return Object.assign({}, state, { thingToChange }); // 或者 return { ...state, ...newState }; } // State 是一個數組 function reducer(state, action) { return [...state, newItem]; }
5. store.subscribe()
5.1 Store 容許使用store.subscribe
方法設置監聽函數,一旦 State 發生變化,就自動執行這個函數。
這api接收一個函數 listener 做爲參數,放在在react component中,每當state變化,就執行對應的該component應該的顯示改變
5.2 該api返回一個終止 該 listener的函數,執行能夠終止監聽
let unsubscribe = store.subscribe(() =>
console.log(store.getState())
);
unsubscribe();
6.對store的解讀,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 }; };
7.reducer的拆分
7.1 Reducer 函數負責生成 State。因爲整個應用只有一個 State 對象,包含全部數據,對於大型應用來講,這個 State 必然十分龐大,致使 Reducer 函數也十分龐大。
請看下面的例子。
const chatReducer = (state = defaultState, action = {}) => { const { type, payload } = action; switch (type) { case ADD_CHAT: return Object.assign({}, state, { chatLog: state.chatLog.concat(payload) }); case CHANGE_STATUS: return Object.assign({}, state, { statusMessage: payload }); case CHANGE_USERNAME: return Object.assign({}, state, { userName: payload }); default: return state; } };
7.2 如何拆分,各管個的,每個子reducer的state,其實只是整個應用的state.subState
//管理視圖的reducer const visibilityFilter = (state = 'SHOW_ALL', action) => { switch (action.type) { case 'SET_VISIBILITY_FILTER': return action.filter default: return state } } export default visibilityFilter
//管理todo任務的reducer const todo = (state, action) => { switch (action.type) { case 'ADD_TODO': return { id: action.id, text: action.text, completed: false } case 'TOGGLE_TODO': if (state.id !== action.id) { return state } return { ...state, completed: !state.completed } default: return state } } const todos = (state = [], action) => { switch (action.type) { case 'ADD_TODO': return [ ...state, todo(undefined, action) ] case 'TOGGLE_TODO': return state.map(t => todo(t, action) ) default: return state } } export default todos
//合併 const todoApp = combineReducers({ todos, visibilityFilter }) export default todoApp
8.工做流程