ReactNative使用Navigation、Redux和Saga

ReactNative使用Navigation、Redux和Saga

备注:这些是本人书写习惯。本人菜鸟一枚,如若有问题希望可以指出来。共同学习进步。

1、创建项目

react-native init DemoApp //创建自己的app

2、添加以下组件

// navigation version 4.+

npm install [email protected]:路由

npm install react-navigation-stack:需要单独安装

npm install react-navigation-tabs:需要单独安装

npm install react-native-reanimated:使用navigation需要安装

npm install react-native-safe-area-context:使用navigation需要安装

npm install @react-native-community/masked-view:使用navigation需要安装

npm install react-native-gesture-handler:使用navigation需要安装

npm install react-native-screens:使用navigation需要安装

npm install react-navigation-redux-helpers:navigation与react-redux关联所需组件

npm install react-redux:状态管理工具

npm install redux:状态管理工具

npm install redux-saga:异步处理工具

3、配置导航

内部页面自行添加

/**
 *  @author Wolf.Ma
 *  @date 2020-04-03 16:28
 *  Navigation 导航
 *  并且与react-redux关联
 */
import React, {Component} from 'react';
import {
    View,
    Image,
    Text,
    StyleSheet,
} from 'react-native';
import {createBottomTabNavigator} from 'react-navigation-tabs';
import {connect} from 'react-redux';
import {createStackNavigator, CardStyleInterpolators} from 'react-navigation-stack';
import {createSwitchNavigator} from 'react-navigation';
import {createReactNavigationReduxMiddleware, createReduxContainer} from 'react-navigation-redux-helpers';

import Home from '../view/home';
import My from '../view/my';
import Login from '../view/login/Login';

const RootTabs = createBottomTabNavigator(
    {
        Home: {
            screen: Home,
            navigationOptions: {
                tabBarLabel: '首页',
                tabBarIcon: ({tintColor, focused}) => (
                    <View>
                        <Text>{'icon'}</Text>
                    </View>
                ),
            },
        },
        My: {
            screen: My,
            navigationOptions: {
                tabBarLabel: '我的',
                tabBarIcon: ({tintColor, focused}) => (
                    <View>
                        <Text>{'icon'}</Text>
                    </View>
                ),
            },
        },
    },
    {
        swipeEnabled: true, // 是否允许横向滑动
        initialRouteName: 'Home', // 设置默认的页面组件
        lazy: true, // 在app打开的时候将底部标签栏全部加载,默认false,推荐改成true
        tabBarPosition: 'bottom', // 设置tabbar的位置,iOS默认在底部,安卓默认在顶部。(属性值:'top','bottom')
        initialRouteParams: {data: 12},
        tabBarOptions: {
            showIcon: true, // 是否显示图标,默认关闭。
            showLabel: true, //是否显示label,默认开启。
            // activeTintColor: Theme.themeColor,
            activeTintColor: '#ff0',
            inactiveTintColor: '#f00',
            // inactiveTintColor: Theme.unSelectColor,
            indicatorStyle: {height: 0},
            style: {
                // marginTop:10,
                padding: 0,
                backgroundColor: '#fff',
                height: 50,
                zIndex: 0,
                position: 'relative',
                borderTopWidth: 0,  //去掉顶部的线条
            },
            labelStyle: {
                fontSize: 14,
                paddingVertical: 0,
                marginTop: -4,
            },
            iconStyle: {
                marginTop: 0,
            },
        },
        animationEnabled: true,
    },
)
const Navigator = createStackNavigator(
    {
        /**
         * 导航模块
         */
        BottomNav: {
            screen: RootTabs,
            navigationOptions: {
                header: null,
            },
        },
        Login: {
            screen: Login,
            navigationOptions: {
                header: null,
            },
        }

    }, {
        initialRouteName: 'BottomNav',
        defaultNavigationOptions: {
            headerShown: false,
            cardStyleInterpolator: (props) => CardStyleInterpolators.forHorizontalIOS(props),
            headerStyle: {
                borderBottomWidth: 0,// 去除导航栏下面的横线
            },
        }
    },
);
/**
 *  设置根路由
 */
export const rootCom = 'Init';
export const RootNavigator = createSwitchNavigator(
    {
        Init: Navigator,
    }, {
        navigationOptions: {
            header: null,
        },
    },
);
/**
 * 1.初始化react-navigation与redux的中间件,
 * 该方法的一个很大的作用就是为reduxifyNavigator的key设置actionSubscribers(行为订阅者)
 * 设置订阅者@https://github.com/react-navigation/react-navigation-redux-helpers/blob/master/src/middleware.js#L29
 * 检测订阅者是否存在@https://github.com/react-navigation/react-navigation-redux-helpers/blob/master/src/middleware.js#L97
 * @type {Middleware}
 */
export const middleware = createReactNavigationReduxMiddleware(
    state => state.nav,
    'root',
);
/**
 * 2.将根导航器组件传递给 reduxifyNavigator 函数,
 * 并返回一个将navigation state 和 dispatch 函数作为 props的新组件;
 * 注意:要在createReactNavigationReduxMiddleware之后执行
 */
const AppWithNavigationState = createReduxContainer(RootNavigator, 'root');

/**
 * State到Props的映射关系
 * @param state
 */
const mapStateToProps = state => ({
    state: state.nav,//v2
});
/**
 * 3.连接 React 组件与 Redux store
 */
export default connect(mapStateToProps)(AppWithNavigationState);

4、reducer配置

4.1 NavigationReducer 导航reducer 配置

/**
 *  @author Wolf.Ma
 *  @date 2020-04-03 17:47
 */
import {NavigationActions} from 'react-navigation';
import RootNavigator, {rootCom} from '../../../nav/Navigation';


const navState = RootNavigator.router.getStateForAction(RootNavigator.router.getActionForPathAndParams(rootCom));

const NavigatorReducer = (state = navState, action) => {
    let nextState;
    switch (action.type) {

        default:
            nextState = RootNavigator.router.getStateForAction(action, state);
            break;
    }
    return nextState || state;
}
export default NavigatorReducer;

4.2 总的Reducer配置

/**
 *  @author Wolf.Ma
 *  @date 2020-04-03 16:26
 *  reducer 汇总
 *
 */
import {combineReducers} from 'redux';
import {rootCom, RootNavigator} from '../../nav/Navigation';

//导航
import NavigationReducer from "./nav/NavigationReducer";

//1.指定默认state
const navState = RootNavigator.router.getStateForAction(RootNavigator.router.getActionForPathAndParams(rootCom));

/**
 * 2.创建自己的 navigation reducer,
 */
const navReducer = (state = navState, action) => {
    const nextState = RootNavigator.router.getStateForAction(action, state);
    // 如果`nextState`为null或未定义,只需返回原始`state`
    return nextState || state;
};

/**
 * 3.合并reducer
 * @type {Reducer | Reducer}
 */
const index = combineReducers({
    nav: NavigationReducer,

})
export default index;

4.3 导航Action配置

/**
 * 返回上一页
 * @returns {{type: *}}
 */
export const goBackPage = () => { //返回上一页
    return {
        type: 'go_back',
    };
};

5、Saga 配置

5.1 异步处理方法编写

/**
 *  @author Wolf.Ma
 *  @date 2020-04-03 17:28
 */
import {put, select, call, delay} from 'redux-saga/dist/redux-saga-effects-npm-proxy.esm';

export function* login() {

}

5.2汇总

/**
 *  @author Wolf.Ma
 *  @date 2020-04-03 17:26
 */
import {takeLatest, put, takeEvery} from 'redux-saga/effects';
//登录模块
import {login} from './login/LoginSaga';

export default function* rootSaga() {
    yield takeLatest('AAA', login);
}

6、Store配置

/**
 *  @author Wolf.Ma
 *  @date 2020-04-03 16:24
 *  store 与中间件 saga
 *  store 存储整个项目的状态
 *  saga 异步事假流
 */

import {createStore, applyMiddleware} from "redux";
import createSagaMiddleware from 'redux-saga';
import reducer from './reducer';
import saga from './saga/index';
import {middleware} from '../nav/Navigation';

//添加中间件saga,支持异步操作
const sagaMiddleware = createSagaMiddleware();

export default (initialAppState) => {
    const store = createStore(
        reducer,
        initialAppState,
        applyMiddleware(
            // loginMiddleware,
            sagaMiddleware,
            middleware,
        ),
    );
    sagaMiddleware.run(saga);
    return store;
}

7、调用

7.1 全局设置

/**
 * @format
 */
import React, {Component} from 'react';
import {AppRegistry} from 'react-native';
import {name as appName} from './app.json';
import {Provider} from 'react-redux';
import configureStore from './src/redux/Store';
import {createAppContainer} from "react-navigation";
import RootNavigator from "./src/nav/Navigation";

console.ignoredYellowBox = ['Warning: BackAndroid is deprecated. Please use BackHandler instead.', 'source.uri should not be an empty string', 'Invalid props.style key'];
console.disableYellowBox = true; // 关闭全部黄色警告
const AppNav = createAppContainer(RootNavigator);
//获取store
const store = configureStore();

export default class Root extends Component {

    render() {
        return (
            //store覆盖整改项目
            <Provider store={store}>
                <AppNav/>
            </Provider>
        )
    }
}

AppRegistry.registerComponent(appName, () => Root);

7.2 页面间使用

/**
 *  @author Wolf.Ma
 *  @date 2020-04-03 16:48
 *  我的
 */

import React, {Component} from 'react';
import {
    StyleSheet,
    View,
    Text
} from 'react-native';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';

class index extends Component {

    constructor() {
        super();
        this.state = {};
    }
    render() {
        return (
            <View>
                <Text>{'Home'}</Text>
            </View>
        );
    }
}

function mapStateToProps(state) {
    return {
        nav: state.nav,
    };
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(index);


const styles = StyleSheet.create({})

你可能感兴趣的:(redux,ReactNative)