//app.js //引入react-redux相關方法 import { Provider } from 'react-redux' //引入redux相關方法 import { createStore, applyMiddleware } from 'redux'; //引入合併事後的reducer import rootReducer from './reducers'; //引入中間件redux-saga import createSagaMiddleware from 'redux-saga'; //引入saga的相關方法 import rootSaga from './saga'; //講reducer方法和中間件saga引入到store中 const sagaMiddleware = createSagaMiddleware(); const store = createStore(rootReducer, applyMiddleware(sagaMiddleware)); sagaMiddleware.run(rootSaga); export default class App extends Component { render() { //此處省略其餘業務代碼 .... return ( <Provider store={store}> //此處省略其餘業務代碼 .... </Provider> ); } } /** * Render the main compoent */ render(<App />, document.getElementById('app'));
//container.js import React, { Component } from 'react'; import PropTypes from 'prop-types'; //引入react-redux組件的connect方法 import { connect } from 'react-redux'; import ExampleComponent from './component'; import ExampleActions from './actions'; //此方法實現了傳入UI組件的props的items的監聽,一旦數據有更新,便會自動更新 const mapStateToProps = (state) => { return { //注意:此處因爲reducers處使用了combineReducers將多個reduce合併,每一個reducer中可能會有同名的state值 //因此state.example.items中的example必定要加,否則會報錯 items: state.example.items } }; //此方法實現了傳入UI組件dispach方法 const mapDispatchToProps = (dispatch) => { return { getItems: () => dispatch(ExampleActions.getItems()) } }; //經過redux中的connect方法將原來的簡單的展現組件變成高階組件 const ExampleContainer= connect(mapStateToProps, mapDispatchToProps)(ExampleComponent); //將容器組件ExampleContainer暴露出來給view層使用 export default ExampleContainer;
//componment.js import React, { Component } from 'react'; import PropTypes from 'prop-types'; class ExampleComponent extends Component { static propTypes = { //經過PropTypes方法檢查容器組件經過connect傳進來的屬性和方法 items: PropTypes.object, getItems: PropTypes.func, //此處省略其餘業務代碼 .... }; //在須要的地方調用觸發函數 componentDidMount() { if (this.props.getItems) { this.props.getItems() } } render() { const { items, //此處省略其餘業務代碼 .... } = this.props; //在須要的地方使用傳進來的數據 Object.keys(items).map((index) => { let item = items[index]; //此處省略其餘業務代碼 .... ); }); return ( //此處省略其餘業務代碼 .... ); } } export default ExampleComponent;
//actions.js import { ITEMS_GET_FETCH } from './actionTypes' class ExampleActions { getItems(searchs) { return { type: ITEMS_GET_FETCH, } } } //講實例化後的ExampleActions暴露給容器組件使用 export default new ExampleActions;
//saga.js import { ITEMS_GET, ITEMS_GET_FETCH} from './actionTypes' //引入effects API的call, put, takeEvery方法 import {call, put, takeEvery} from 'redux-saga/effects'; //引入封裝fetch方法的cfetch import {cfetch, checkStatus, parseJSON} from '../../utils/cfetch'; //worker saga這裏實際上是有接收參數的 這個參數action就是redux執行dispatch方法中的參數 function* fetchGetItems(){ try { const p =function () { return cfetch('/clients/name') .then(checkStatus) .then(parseJSON) .then(function (json) { return json }); }; //執行異步函數,此時本次的worker saga事件會暫停直到異步函數執行完成 //當前是一個Promise,在該Promise的狀態從pending轉到resolve或reject以前,當前worker saga變出於暫停狀態 //若狀態爲resolve,則將帶着返回值繼續執行 //若狀態爲reject,則將在Generator中拋出一個錯誤,被catch捕獲 const data = yield call(p); //指示中間件發起一個action到Store層,做用和 redux 中的 dispatch相同, 這個 effect 是非阻塞型的 //會異步執行,整個Generator執行完畢 yield put({type: ITEMS_GET, clients: Object.assign({},data)}); } catch (e) { console.log(e); } } //watcher saga function* rootSaga() { //監聽來自action層的觸發,攔截到後調用對應的worker saga(本例子中的fetchGetItems) //takeEvery容許多個worker saga實例同時啓動 yield takeEvery(ITEMS_GET_FETCH, fetchGetItems); } export default rootSaga;
import { ITEMS_GET } from './actionTypes' //定義數據的初始值 const initialState = { items: {}, }; const exampleReducer = (state = initialState, action) => { switch (action.type) { //sage層攔截到action的觸發,進行一系列異步操做而後觸發reducer以下,並將action傳進來 //這裏的state不是覆蓋,而是將原來的state和更新的內容合併生成新的state,而後交給store處理 case ITEMS_GET: return {...state, items: action.items}; default: return state; } }; export default exampleReducer;