//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;