zoukankan      html  css  js  c++  java
  • 基于React+Router+Redux+Sagas+fetch+ant Design +less + es6+mockjs的项目过程总结

    app.js是首页面,路由放此。
    sagas在此页面被引用。
     
    import rootSaga from './sagas'
    const store = configureStore(initialState)
    store.runSaga(rootSaga); 

    1)FL.js    
    修改对应的接口Path值,便于后期对接口地址的管理。
    SupSearch:'/api/Order/supSearch.json',
    SupState:'/api/Order/supState.json',
    2)sagas  
    中间件,只会在应用启动时调用(但初始启动的sagas可能会动态的调用其它sagas),用于监听发起的action,然后决定这个action用来做什么。
    如:1.发起一个异步调用(ajax请求) 2.发起其它的action到store。 3.调用其它的sagas
     
    index.js里面放所有的sagas。
    import { watchGetAccountSaga } from './account'
    import {supSearch} from './supSearch'
    export default function* rootSaga() {
        yield [
            // 更多
            watchGetAccountSaga(),
            supSearch(),
        ]
    }
    子saga:有两个Generator函数。其中一个通过while(true),take方法来一直监听action。
    只有当此事件被dispatch则fork第二个Generator函数。(此步骤避免了同时发起多个不必要的请求。
    只有当view页面componentWillMount 才触发此action,发起请求。)
    componentWillMount(){  
            this.props.initialDispatch()
        },
    import { SUPSEARCHACTION, supSearchSucceed,supSearchFailed} from '../actions/sup'
    export function* supSearch() {
        while (true) {
            yield take(SUPSEARCHACTION)
            yield fork(fetchSupSearchApi)
        }
    }
    第二个Generator方法主要用来生成fetch请求。
    任务要被beginTask和endTask包裹。在请求成功之后,将请求到的数据dispatch一个对应的action(成功:supSearchSucceed(res) ) 失败(supSearchFailed(e) )。
     
    function* fetchSupSearchApi(){
        try {
            yield put( beginTask() )
            const response = yield call(fetch, FL.PATH.API.SupSearch)
            const res = yield response.json()
            if (!res) {
                return false
            } else {
                yield put( supSearchSucceed(res) )   (成功)
            }
        } catch (e) {
            yield put( supSearchFailed(e) )   (失败)
        } finally {
            yield put( endTask() )
        }
    }
    mockjs也是放在此文件中。
     
    // mock 代码放在 __DEBUG__ 代码块内,生产环境会删除代码块
    if (__DEBUG__) {
        let data = Mock.mock({
            'Status': '200',
            'Position': '001',
            'ErrorCode': '001',
            'Data|1-10': [{
                'productNumber': /[A-Z][A-Z]d{3}[a-z]d{3}/,
                'productName': '@ctitle(3, 5)',
                'supplierName': '@ctitle(3)',
                'productStockStatus|1-100': 1,
                'faceValue|1-1000': 1,
                'productPrice|1-100': 1,
                'type|1-4': 1,
                'averageChargeTime':'@natural(0,200)'+'min',
                'complaintRate':'@natural(0,100)'+'%',
                'successRate': '@natural(0,100)'+'%',
                'today|1-100': 1,
                'week|1-1000':1 ,
                'month|1-10000': 1,
                'purchaseApplyStatus': '@boolean()'
            }]
        });
     
        fetchMock.mock(FL.PATH.API.SupSearch, data);
        // fetchMock.mock(FL.PATH.API.ACCOUNT, 404);
    }
    3)action
    在对应的action文件sup.js中,
     
    export const SUPSEARCHACTION = 'SUPSEARCHACTION'
    export const SUPSEARCH_SUCCEED = 'SUPSEARCH_SUCCEED'
    export const SUPSEARCH_FAILED = 'SUPSEARCH_FAILED'
    分别对应触发,请求成功、请求失败的action:
    export function supSearchAction(){
        return {
            type:SUPSEARCHACTION
        }
    }
    export function supSearchSucceed(items){
        return {
            type:SUPSEARCH_SUCCEED,
            items
        }
    }
    export function supSearchFailed(error) {
        return {
            type: SUPSEARCH_FAILED,
            error,
        }
    }
     
    4)reducer
    index.js中为总reducer。通过import将各个reducer引入进来,通过combineReducer将各个子reducer结合起来。configureStore.js中引入此rootReducer。
     
    import supSearch from './supSearch'
    import supState from './supState'
     
     
    const rootReducer = combineReducers({
        routing: routerReducer,
        supSearch,
        supState,
    })
     
    export default rootReducer
    将action的三种type值引入,触发不同的type值会有不同的处理。
    1、当触发SUPSEARCHACTION时,将isfetching设为true,代表开始请求数据。
    2、当触发SUPSEARCH_SUCCEED时,将isfetching设为false,代表请求完成,成功,并将请求到的参数返回给items,items的值同步到state当中。
    3、当触发SUPSEARCH_FAILED时,将isfetching设为false,代表请求完成,失败。返回错误。
    import {SUPSEARCHACTION,SUPSEARCH_SUCCEED,SUPSEARCH_FAILED} from '../actions/sup'
     
    export default function supSearch (state = {}, action) {
        switch (action.type) {
            case SUPSEARCHACTION:
                return {
                    ...state,
                    isfetching:true,
                }
            case SUPSEARCH_SUCCEED:
                return {
                    ...state,
                    isfetch:false,
                    items: action.items,
                }
            case SUPSEARCH_FAILED:
                return {
                    ...state,
                    isfetching: false,
                    error: action.error,
                    };
            default:
                return state
        }
    }
     
    5)containers
    用于将state进行处理,处理好的数据通过connect传递给component中的view页面  涉及到reselect(创建选择器)。
     
    import { connect} from 'react-redux'  
    import SupSearch from '../components/SupSearch/js/SupSearch'
    import {supSearchAction} from '../actions/sup' 
    import {createSelector } from 'reselect'
     
    const defaultValue = [];
    const stateItemSelector = (state) =>state.supSearch.items || defaultValue
    const stateSelector = createSelector (
        [stateItemSelector],
        (stateItem) => {
            return stateItem
        }
    )
    const mapStateToProps = (state) =>{
        return {
            items:stateSelector(state),
        }
    }
    const mapDispatchToProps = (dispatch) =>{
        return {
            initialDispatch(){
                dispatch(supSearchAction())
            },
        }
    }
    export default connect(
        mapStateToProps,
        mapDispatchToProps
    )(SupSearch)
    6)component
    此部分即为view模块。只有当组件即将被渲染时,才发起action,触发saga部分的yield take(SUPSEARCHACTION)
    initialDispatch方法即为5)中mapDispatchToProps传过来的方法。
     
    componentWillMount(){
            this.props.initialDispatch()
        },
     
     
     
  • 相关阅读:
    在Ubuntu中通过update-alternatives切换软件版本
    SCons: 替代 make 和 makefile 及 javac 的极好用的c、c++、java 构建工具
    mongodb 的使用
    利用grub从ubuntu找回windows启动项
    How to Repair GRUB2 When Ubuntu Won’t Boot
    Redis vs Mongo vs mysql
    java script 的工具
    python 的弹框
    how to use greendao in android studio
    python yield的终极解释
  • 原文地址:https://www.cnblogs.com/mian-bread/p/6094126.html
Copyright © 2011-2022 走看看