美文网首页React Native开发经验集React Native开发
React Native Dva Typescript 柳暗花明

React Native Dva Typescript 柳暗花明

作者: ArthurWang | 来源:发表于2018-07-22 14:07 被阅读21次

    引子

    上次我们说到React Native Redux Typescript使用 redux-thunk or redux-saga,相信对于刚入门的同学来说,看完博客理解起来感觉亚历山大。

    那么,我们需要一个可以完整实现redux多种操作,并且简单易懂的封装好的框架。
    难道真的有这样的框架吗?
    对于要解决最一线,最急切的需求。这个可以有,这个必须有。

    web页面快速上手

    点这里:https://github.com/dvajs/dva-docs/blob/master/v1/zh-cn/getting-started.md
    快速上手

    通过上面的快速介绍文档,我们可以了解到 dva框架是如此的方便快捷已与学习和应用。

    最小化实现dva Dva-Core

    添加依赖包引用

    执行

    yarn add dva-core  redux-logger
    yarn add -D  @types/redux-logger
    

    定义dva-core “声明”

    严格意义上将,我这个定义的不是声明,是对dva-core封装了一遍

    新建文件 utils/dva.tsx

    import React from 'react';
    import { Provider, connect } from 'react-redux';
    let {create} = require("dva-core");
    export { connect };
    export interface Options {
      models: Model[];
      extraReducers?: any;
      initialState: any;
      onError: (e: any) => void;
      onAction: any[];
    }
    
    export function dva(options: Options) {
      const app = create(options);
      options.models.forEach((model: Model) => app.model(model));
      app.start();
      const store = app._store;
    
      app.start = (container: any) => () => <Provider store={store}>{container}</Provider>;
      app.getStore = () => store;
    
      return app;
    }
    
    import {
      Reducer,
      Action,
      ReducersMapObject,
      Dispatch,
    } from 'redux';
    
    export interface EffectsCommandMap {
      put: <A extends Action>(action: A) => any;
      call: Function;
      select: Function;
      take: Function;
      cancel: Function;
      [key: string]: any;
    }
    export interface EffectsMapObject {
      [key: string]: Effect | EffectWithType;
    }
    export interface ReducerEnhancer {
      (reducer: Reducer<any>): void;
    }
    export interface SubscriptionAPI {
      dispatch: Dispatch<any>;
    }
    export type ActionWithPayload = {action: Action, payload: any};
    export type EffectType = 'takeEvery' | 'takeLatest' | 'watcher' | 'throttle';
    export type EffectWithType = [Effect, { type: EffectType }];
    export type Effect = (action: ActionWithPayload, effects: EffectsCommandMap) => void;
    export type ReducersMapObjectWithEnhancer = [ReducersMapObject, ReducerEnhancer];
    export type Subscription = (api: SubscriptionAPI, done: Function) => void;
    export interface SubscriptionsMapObject {
      [key: string]: Subscription;
    }
    export interface Model {
      namespace: string;
      state?: any;
      reducers?: ReducersMapObject | ReducersMapObjectWithEnhancer;
      effects?: EffectsMapObject;
      subscriptions?: SubscriptionsMapObject;
    }
    

    为了方便看到异步效果,我们新建个通用工具
    新建文件 utils/index.ts

    export const delay = (time:any) => new Promise(resolve => setTimeout(resolve, time))
    

    定义Model

    新建 models/count.ts

    import {delay} from '../utils/index';
    import { Model } from "../utils/dva";
    type countState=number
    export default {
      namespace: 'count',
      state: 0 as countState,
      reducers: {
        add(state:countState) { return state + 1; },
        minus(state:countState) { return state - 1; },
      },
      effects: {
        *addWithDelay(action, { call, put }) {
          console.log('====================================');
          console.log(action);
          console.log('====================================');
          console.log('====================================');
          console.log(call);
          console.log('====================================');
          console.log('====================================');
          console.log(put);
          console.log('====================================');
          yield call(delay, 1000);
          yield put({ type: 'add' });
        }
      },
    } as Model;
    

    然后新建展示页面 routes/Home.tsx

    import React, { Component } from "react";
    import {
        StyleSheet,
        Text,
        View,
        Button
    } from "react-native";
    
    import {connect} from '../utils/dva';
    interface Props {
        count:number,
        dispatch?:any
    }
    interface State {
    }
    class App extends Component<Props, State> {
        render() {
            return (
                <View style={styles.container}>
                    <Text style={styles.text}>
                        Welcome to React Native!
                        
                    </Text>
                    <Text style={styles.text}>
                        Count: { this.props.count }
                    </Text>
                    <Button title="+" onPress={() => { this.props.dispatch({ type: 'count/add' }); }} />
                    <Button title="-" onPress={() => { this.props.dispatch({ type: 'count/minus' }); }} />
                    <Button title="+ async" onPress={() => { this.props.dispatch({ type: 'count/addWithDelay' }); }} />
                </View>
            );
        }
    }
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            justifyContent: "center",
            alignItems: "center",
            backgroundColor: "#F5FCFF",
        } ,
        text: {
            fontSize: 20,
            textAlign: "center",
            margin: 10,
        },
    });
    
    function mapStateToProps(state:any) {
        return {
          count: state.count,
        };
      }
      export default connect(mapStateToProps)(App);
    

    初始化dva
    新建 index.tsx

    import React from 'react';
    import { AppRegistry, AsyncStorage } from 'react-native';
    import {createLogger} from 'redux-logger';
    import {dva}from './utils/dva'
    import count from './models/count'
    import Home from './routes/Home';
    const app = dva({
        initialState: {},
        models: [count],
        extraReducers: {},
        // models:[m],
        onError(e: any) {
            console.error('onError', e);
        },
        onAction: [createLogger({collapsed: true})],
    
    });
    const App = app.start(<Home />)
    export default App;
    

    然后我们运行项目看看效果:

    react-native-redux-saga-dva-typescript-20187213142

    相关文章

      网友评论

      本文标题:React Native Dva Typescript 柳暗花明

      本文链接:https://www.haomeiwen.com/subject/igvlmftx.html