React Native redux理解

作者: 一亩三分甜 | 来源:发表于2019-07-24 21:04 被阅读0次

    React-redux提供Provider和connect两个接口链接

    • Provider组件在应用最外层,传入store即可,只用一次
    • Connect负责从外部获取组件需要的参数
    • Connect可以用装饰器的方式来写
    • 你要state什么属性放到props里
    • 你要什么方法,放到props里,自动dispatch
    • 两个reducers,每个reducers都有一个state
    • 复杂redux应用,多个reducer,用combineReducers合并
    • 合并所有reducer,并且返回
    • 把store.dispatch方法传递给组件,内部可以调用修改状态
    • connect负责链接组件,给到redux里的数据放到组件的属性里
    1.负责接受一个组件,把state里的一些数据放进去,返回一个组件
    2.数据变化的时候,能够通知组件
    
    • Provider,把store放到context里,所有的子元素可以直接取到store

    redux理论抽象,写一个例子:写一个需要登录的例子,有两个reducer。

    0.gif

    1.两个reducer:一个reducer用来控制登录态,一个用来管理机枪数量。通过combineReducers()合并到一个reducer中。

    • authReducer:控制登录态,有登录和注销两个action。
    const LOGIN = 'LOGIN'
    const LOGOUT = 'LOGOUT'
    
    export function auth(state={isAuth:false,user:'李云龙'},action){
        switch(action.type){
            case LOGIN:
                return {...state,isAuth:true}
            case LOGOUT:
                return {...state,isAuth:false}
            default:
                return state;
        }
    }
    
    export function login(){
        return {type:LOGIN}
    }
    export function logout(){
        return {type:LOGOUT}
    }
    export default auth;
    
    • gunReducer:控制机枪数量,有增加机枪,减少机枪,过两天再加(异步)三个action。
    const ADD_GUN = '加机关枪'
    const REMOVE_GUN = '减机关枪'
    function counter (state=10,action){
      switch(action.type){
          case ADD_GUN:
          return state + 1;
          case REMOVE_GUN:
          return state - 1;
          default:
              return 10;
      }
    }
    
    export function addGun(){
        return {type:ADD_GUN}
    }
    export function removeGun(){
        return {type:REMOVE_GUN}
    }
    export function addGunAsync(){
        return dispatch => {
            setTimeout(
                ()=>{dispatch(addGun())
            },2000)
        }
    }
    export default counter;
    
    • 合并两个reducer:authReducer和gunReducer,可能根据业务需要会有多个reducer。
    import counter from '../reducer/gunReducer';
    import auth from '../reducer/authReducer';
    import {combineReducers} from 'redux';
    export default combineReducers({counter,auth});
    

    2.reducer传入store中,有异步会用到中间件。

    import {createStore,applyMiddleware} from 'redux';
    import thunk from 'redux-thunk';
    import reducer from '../reducer/reducer'
    
    export default () => {
        //根据 reducer 初始化 store
        const store = createStore(reducer,applyMiddleware(thunk));
        return store;
    }
    

    3.App中引入store,第一层包装Provider。

    import React, { Component } from 'react';
    //引用外部文件
    import {Provider} from 'react-redux';
    import {createAppContainer,createStackNavigator} from 'react-navigation';
    import Main from './app/containers/Main';
    import LoginScreen from './app/containers/LoginScreen';
    import contextScreen from './app/containers/ContextScreen';
    import ContextToPropScreen from './app/containers/ContextToPropScreen';
    import configureStore from './app/redux/store/store';
    const store = configureStore();
    let RootStack = createStackNavigator({
      mainScreen:Main,
      loginScreen:LoginScreen,
      contextToPropScreen:ContextToPropScreen,
      contextScreen:contextScreen
    });
    let Navigation = createAppContainer(RootStack);
    //调用 store 文件中的 mainReducer常量中保存的方法
    export default class App extends Component {
      render() {
        return (//第一层包装,为了让 main 能够拿到 store
          <Provider store={store}>
          <Navigation />
          </Provider>
          )
      };
    }
    
    

    4.引入reducer中的action,在要用到redux中保存的action和state的页面获取state和action,链接器进行链接。链接上之后state和action均以this.props.num,this.props.isAuth,this.props.login,this.props.logout方式调用。

    import { connect } from 'react-redux';
    import { addGun, removeGun, addGunAsync } from '../redux/reducer/gunReducer';
    import {login,logout} from '../redux/reducer/authReducer'
    // 获取 state 变化
    const mapStateToProps = (state) => {
        return {
            num: state.counter,//counter这个reducer中只有一个变量,可以直接赋值。
            isAuth:state.auth.isAuth//redux中有两个reducer,auth这个reducer中又包含两个state:isAuth和user。
        }
    }
    // // 发送行为
    const mapDispatchToProps = ({
        addGun: addGun,
        removeGun: removeGun,
        addGunAsync: addGunAsync,
        login:login,
        logout:logout
    });
    // const actionCreators = { addGun, removeGun, addGunAsync,login,logout}
    // 进行第二层包装,生成的新组件拥有 接受和发送 数据的能力
    Main = connect(mapStateToProps, mapDispatchToProps)(Main)
    export default Main
    

    5.render()里面判断是否登录,若登录了,跳到独立团页面,未登录跳登录页。

        render() {
            return(
             <View style={{
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center',
                backgroundColor: '#F5FCFF',
            }}>
               {this.props.isAuth ? this._independentView():this._loginView()}
                 </View>
            );
        }
    

    6.点击申请武器则调用this.props.addGun,进入gunReducer响应对应key:ADD_GUN,默认state为10,state则加1。上交武器则调用this.props.removeGun,进入gunReducer响应对应key:REMOVE_GUN,state则减1,点击拖两天再给则调用this.props.this.props.addGunAsync,模拟异步延时两秒执行addGun(),两秒后state加1;点击登录,进入authReducer响应对应key:LOGIN,isAuth为true,点击注销,进入authReducer响应对应key:LOGOUT,isAuth为false。

    _independentView() {
            return (
            <View>
                <Text style={{
                    fontSize: 36,
                    textAlign: 'center',
                    margin: 10,
                }}>
                    独立团
            </Text>
                <Text style={{ fontSize: 24 }}>
                    现在有机枪{this.props.num}把
            </Text>
                <TouchableOpacity style={{ marginTop: 36 }} onPress={this.props.addGun}>
                    <Text style={{ fontSize: 24,alignSelf:'center',marginTop:8}}>申请武器</Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={this.props.removeGun}>
                    <Text style={{ fontSize: 24,alignSelf:'center',marginTop:8}}>上交武器</Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={this.props.addGunAsync}>
                    <Text style={{ fontSize: 24,alignSelf:'center',marginTop:8 }}>拖两天再给武器</Text>
                </TouchableOpacity>
                <TouchableOpacity style={{ marginTop: 36 }} onPress={this.props.logout}>
                    <Text style={{ fontSize: 24,alignSelf:'center' }}>注销</Text>
                </TouchableOpacity>
            </View>
            )
        }
        _loginView() {
            return(
            <View>
                <Text>你没有权限,需要登录才能看</Text>
                <TouchableOpacity onPress={
                        this.props.login
                    }>
                    <Text style={{ fontSize: 24,alignSelf:'center',marginTop:36}}>登录</Text>
                </TouchableOpacity>
            </View>
            )
        }
    

    Demo。

    相关文章

      网友评论

        本文标题:React Native redux理解

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