React Native redux理解

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。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容