redux
redux概念
Redux是JavaScript應用程序的可預測狀態容器。
redux 設計思想
- Web 應用是一個狀態機,視圖與狀態是一一對應的。
- 所有的狀態,保存在一個對象里面。
基本概念和 API
store
Store 就是保存數據的地方,你可以把它看成一個容器。整個應用只能有一個 Store。
Redux 提供createStore這個函數
state
Store對象包含所有數據。如果想得到某個時點的數據,就要對 Store 生成快照。這種時點的數據集合,就叫做 State。
當前時刻的 State,可以通過store.getState()拿到。
Redux 規定, 一個 State 對應一個 View。
Action
State 的變化,會導致 View 的變化。但是,用戶接觸不到 State,只能接觸到 View。所以,State 的變化必須是 View 導致的。Action 就是 View 發出的通知,表示 State 應該要發生變化了。Action 是一個對象。其中的type屬性是必須的,表示 Action 的名稱??梢赃@樣理解,Action 描述當前發生的事情。改變 State 的唯一辦法,就是使用 Action。它會運送數據到 Store。
store.dispatch()是 View 發出 Action 的唯一方法。
Reducer
Store 收到 Action 以后,必須給出一個新的 State,這樣 View 才會發生變化。這種 State 的計算過程就叫做 Reducer。Reducer 是一個函數,它接受 Action 和當前 State 作為參數,返回一個新的 State。
Redux 的工作流程
用戶發送action ,store 自動調用reducer,并且傳入當前state和收到action,reducer 返回新的state,state 一有改變,store就會調用監聽函數subscribe ,listener可以通過store.getState()得到當前狀態,state改變,重新渲染 View
異步操作(redux-saga)
獲取驗證碼示例:
/component/verifyCode
<button onClick={this.handClick}>獲取驗證嗎</button>
handClick(){
const {dispatch} = this.props;
//發送異步請求 action
dispathc(userAction.verifyCode({
mobile:mobile
}));
}
/actions/userActions
//發送請求
const VERIFYCODE = 'VERIFYCODE';
//獲取數據成功
const VERIFYCODE_SUCCESS = 'VERIFYCODE_SUCCESS';
//獲取數據失敗
const VERIFYCODE_FAIL = 'VERIFYCODE_FAIL';
//actionCreate
//payload 傳遞參數
export const verifyCode = (payload) => ({type:VERIFYCODE,payload});
export const verifyCode_Success = (data) => ({type:VERIFYCODE_SUCCESS,data});
export const verifyCode_Fail = (error) => ({type:VERIFYCODE_FAIL,error});
/reducers/userReducers
function getVerifyCode(state={isFetching:false,data:null},action){
//根據action type 返回state
switch(action.type){
case 'VERIFYCODE':
return {
...state,
isFetching:true
}
case 'VERIFYCODE_SUCCESS':
return {
...state,
isFetching:false,
data:action.data
}
case 'VERIFYCODE_FAIL':
return {
...state,
isFetching:false,
error:action.error
}
default:
return state;
}
}
export const rootReducer = combineReducers({
getVerifyCode
})
/sagas/userSaga
function* getVerifyCode(action){
//調用異步函數
const data = yield call(service.getVerifyCode,action.payload);
if(data.status===0){
//獲取數據成功,發送成功action
yield put(userActions.verifyCode_Success(data.content));
}else{
//獲取數據失敗,發送失敗action
yield put(userActions.verifyCode_Fail('系統錯誤'));
}
}
export function* watch(){
//監聽action type VERIFYCODE ,觸發函數getVerifyCode
yield takeEvery('VERIFYCODE', getVerifyCode),
}
/store/index
import {
createStore,
applyMiddleware
} from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from '../reducers';
export default function configureStore() {
const sagaMiddleware = createSagaMiddleware();
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));
store.runSaga = sagaMiddleware.run;
return store;
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {
Provider,
} from 'react-redux';
import rootSaga from './js/sagas';
import configureStore from './js/store';
import App from './js/containers/App';
const store = configureStore();
store.runSaga(rootSaga);
const render = (Component) => {
ReactDOM.render(
<Provider store={store}>
<Component/>
</Provider>,
document.getElementById('root')
);
};
render(App);