react + redux笔记

date: 2018.03.05; modification:2018.03.31

目录:

1 react navigation与redux一起使用

  1. 准备环境

    yarn add redux react-redux react-navigation react-navigation-redux-helpers

components/Screenxxx1.js:


    import React, { Component } from 'react';
    import { StyleSheet, Text, View, Button } from 'react-native';

    export default class Screenxxx1 extends Component {
        static navigationOptions = {
            title: 'Screenxxx1',
        };

        render() {
            return (
                
                    Hello Screenxxx1
                
            );
        }
    }

  1. 在原有Navigation上添加wrapper:

将原本的:

export const AppNavigator = StackNavigator({
  Sxxx1: {screen: Screenxxx1},
  Sxxx2: {screen: Screenxxx2},
});

改为:

components/AppNavigatorCtn.js


    import React, { Component } from 'react';
    import { connect } from 'react-redux'
    import { addNavigationHelpers } from "react-navigation";
    import { StackNavigator } from 'react-navigation';
    import {
        createReduxBoundAddListener,
        createReactNavigationReduxMiddleware,
    } from 'react-navigation-redux-helpers';

    import { navigation } from '../actions'

    import Screenxxx1 from './Screenxxx1Ctn';
    import Screenxxx2 from './Screenxxx2Ctn';


    export const AppNavigator = StackNavigator({
      Sxxx1: {screen: Screenxxx1},
      Sxxx2: {screen: Screenxxx2},
    });

    // -----------------------------------------------------------------------------
    // Note: createReactNavigationReduxMiddleware must be run before createReduxBoundAddListener
    export const navReduxMiddleware = createReactNavigationReduxMiddleware(
      "root",
      state => state.nav,
    );

    // -----------------------------------------------------------------------------
    const addListener = createReduxBoundAddListener("root");
    class App extends Component {
      render() {
        return (
            
        );
      }
    }

    const mapStateToProps = (state) => ({
      nav: state.nav
    });

    export default AppNavigatorCtn = connect(mapStateToProps)(App);

这里export了3个东西: * AppNavigator: 给负责响应导航reducer用. * navReduxMiddleware: createStore()时需要传入. * AppNavigatorCtn: 对navigation控件进行封装的redux container.

  1. reducer中增加nav

reducers/nav.js:


    import { NavigationActions } from 'react-navigation';
    import { AppNavigator } from '../containers/AppNavigatorCtn';

    const initialState = AppNavigator.router.getStateForAction(AppNavigator.router.getActionForPathAndParams('Sxxx1'));
    console.log('########## initialState:', initialState);

    const nav = (state = initialState, action) => {
        const nextState = AppNavigator.router.getStateForAction(action, state);
        console.log('nav nextState:', nextState);


        // Simply return the original `state` if `nextState` is null or undefined.
        return nextState || state;
    };

    export default nav;

reducers/index.js:


    import { combineReducers } from 'redux'
    import nav from './nav'

    const rootReducer = combineReducers({
        nav
    })

    export default rootReducer

  1. actions中添加navigation:

actions/index.js:


    export const navigation = (gotoScreen) => ({
        type: 'ACTION_NAVIGATE',
        gotoScreen: gotoScreen
    })

  1. APP入口用react-navigation-redux-helpers进行封装

app.js:


    import React, { Component } from 'react';
    import { createStore, applyMiddleware } from 'redux'
    import { Provider } from 'react-redux'

    import AppNavigatorCtn from './containers/AppNavigatorCtn'
    import { navReduxMiddleware } from './containers/AppNavigatorCtn'
    import rootReducer from './reducers'


    const store = createStore(
        rootReducer,
        applyMiddleware(navReduxMiddleware),
    );

    export default class MyApp extends Component {
        render() {
            return (
                
                    
                
            )
        }
    }

index.js:


    import { AppRegistry } from 'react-native';
    import VideoCall from './App';

    AppRegistry.registerComponent('VideoCall', () => VideoCall);

  1. 在页面控件中进行导航:
    
    import { connect } from 'react-redux'
    import { NavigationActions } from "react-navigation";

    function mapStateToProps (state, ownProps) {
        return {}
    }

    function mapDispatchToProps(dispatch, myProps) {
        return {
            onClick: () => {
                console.log('dispatch ACTION_NAVIGATE');
                dispatch(
                    NavigationActions.navigate({ routeName: 'Sxxx1' })
                );
                    //NavigationActions.goback()
            }
        }
    }

    export default Screenxxx2Ctn = connect(
        mapStateToProps,
        mapDispatchToProps
    )(Screenxxx2)