react native

2018-05-24-redux

2018-06-02  本文已影响0人  简书Boss

声明:本文纯属个人学习笔记,本无意发布,参考文档注于文章结尾;
转载请注明原文地址

redux提供了一套机制来组织管理整个应用状态。

   Redux有三部分组成:store,action,reducer。

   store:维护全局的state,以及将action和reducer结合起来。

   action:用来传递state的信息。(比如:我们在action中处理登陆操作,将返回的user对象传递给对应的reducer.)

   reducer: reducer是简单的处理函数,通过传入旧的state和指示操作的action来更新state,从而达到页面的刷新。

首先安装相关库:

安装redux:npm install --save redux
安装redux绑定库:npm install --save react-redux
安装开发者工具:npm install --save-dev redux-devtools
安装异步action构造器:npm install --save redux-thunk
在集成之前熟悉下一般基于Redux的目录结构:
├── src #开发目录
| |
| ├──constants #ActionTypes和Urls
| |
| ├──actions #actions的文件
| |
| ├──components #内部组件
| |
| ├──containers #容器组件
| |
| ├──reducers #reducer文件
| |
| ├──stores #store配置文件
| |
| └──utils #工具
|
├── node_modules #包文件夹
├── .gitignore
├── index.js #入口文件
└── package.json
  1. 首先创建全局的store。(一般在stores文件中写个配置文件)
import  thunk from 'redux-thunk';
import {applyMiddleware, createStore}from 'redux';
import RootReducer from '../reducers/index';
const middlewares = [thunk];

const createSoreWithMiddleware=applyMiddleware(...middlewares)(createStore);

//配置store信息
export default function configureStore(initialState){
  const store=createSoreWithMiddleware(RootReducer,initialState);
  return store;
}

或者这样


import thunk from 'redux-thunk';
import { createStore, applyMiddleware, compose } from 'redux';
import rootReducer from '../reducers/rootReducer';

let store = createStore(rootReducer, {}, compose(
  applyMiddleware(thunk),
  // window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  window.devToolsExtension ? window.devToolsExtension() : f => f
));

export default store;
  1. (设定类型type) constans文件夹内新建文件actionType,用来划分事件类别
export const LOGIN_DOING = "LOGIN_DOING";//登录中
export const LOGIN_SUCCESS = "LOGIN_SUCCESS";//登录成功
export const LOGIN_ERROR = "LOGIN_ERROR";//登录失败
export const MAIN_DATA = "MAIN_DATA";//主页数据
export const MAIN_DATA_INDEX = "MAIN_DATA_INDEX";//
export const MINE_DATA = "MINE_DATA";//我的页面数据
  1. (设定预处理消息过程)actions文件夹内,新建xxxAction文件,用来给预处理消息区分各个事件的类别(其他操作比如说数据请求等都是在这些xxxAction文件里面写逻辑代码)
// loginAction
import * as types from '../../constants/actionTypes';

export function login(){
  return{
    type:types.LOGIN_DOING,
    status:'登陆中...'
  }
}

export function login2(status){
  return{
    type:types.LOGIN_DOING2,
    status
  }
}
  1. (设定消息的具体处理过程)reducers文件夹内新建xxxReducer文件,用来处理对应的state的变化(数据拼接的一些操作)
import * as types from  '../../constants/actionTypes';

export default function loginIn(state={ status:'请登陆'},action) {  //这里的loginIn需要在总的reducer中去合并
  switch(action.type){
    case types.LOGIN_DOING:
      return{
        ...state,
        status:'登录中...123'
      }
      break;
    case types.LOGIN_DOING2:
      return{
        ...state,
        status:'LOGIN_DOING2'
      }
      break;
    default:
      return state;
  }
}
  1. 项目内可能并不是只有一个redux操作逻辑,现在给所有的reducer建立一个统一的入口,reducers文件夹内新建index.js文件,作为统一入口;
import { combineReducers }from 'redux';
import loginIn from './loginReducer/loginReducer';

const RootReducer =combineReducers({     //应为一个app不可能只有一个reducer所以这个是用来合并所有的reducer的
  loginIn,
});
export default RootReducer;
  1. 创建项目中的store,用来管理所有的state,store文件夹内新建ConfigureStore.js文件
步骤1
  1. 现在action,reducer,store都存在了,接下来我们在处理视图部分,即Provider.先写Provider外壳,并将整个APP包裹在内;
    src文件夹内,新建Root.js文件,该文件内实现Provider对视图部分的包裹
import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View
} from 'react-native';
import RootPage from  './src/components/rootPage/rootPage';
import { Provider }from 'react-redux';
import configureStore from './src/stores/ConfigureStore';
import AppNavigator from './src/components/routers/AppNavigator';
const store=configureStore();//
export default class App extends Component{
  render() {
    return (
      <Provider store={store}>
        <AppNavigator></AppNavigator>
      </Provider>
    );
  }
}
  1. 实现页面(注意此处有很关键的一步,需要在页面内实现组件和store的关联,之所以能够实现不同的组件关联不同的state也是在这一步进行的)
//
import React,{ Component }from 'react';
import {
  View,
  Text,
  StyleSheet
}from 'react-native';
import {
  NavigationActions
}from 'react-navigation';
import * as LoginAction from '../../action/loginAction/loginAction';
import { connect} from 'react-redux';
class LoginPage extends Component{
  onLogin() {
    const resetAction = NavigationActions.reset({
      index: 0,
      actions: [
        NavigationActions.navigate({ routeName: 'TabBar'})
      ]
    });
    this.props.navigation.dispatch(resetAction);

    // this.props.navigation.navigate('Work');
  }
  render() {
    const {status,login,login2}=this.props;//这个必须有,是将xxxAction里面定义的方法注入进来,这样在页面中才可以使用,(有两种写法)

           //例如这个页面中的点击登录1和点击登录2中的onPress
           //还有status,初始状态在xxxAction中可以不用赋值,请看步骤3中的login2的status,在loginAction中并没有给初始值,它的初始值会来自对应的xxxReducer中的status,(这里的话可以参考步骤4的loginReducer)
    return (
      <View style={styles.container}>
        <Text style={styles.instructions}>
          状态:{status}
        </Text>
        <Text style={styles.welcome} onPress={()=>login()}>
          点击登录1
        </Text>
        <Text style={styles.welcome} onPress={()=>login2()}>
          点击登录2
        </Text>
        <Text onPress={()=>this.onLogin()}>
          点击切换导航
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({这里的样式省略...});
export default connect(//写法一:
  (state)=>({
    status:state.loginIn.status      //注意看这里面的写法不一样哦,对应的上面的const {status,login,login2}=this.props;的写法也不一样呐
  }),
  (dispatch)=>({
    login:()=>dispatch(LoginAction.login()),
    login2:()=>dispatch(LoginAction.login2())
  })
)(LoginPage);
写法二:(这是来自另一个页面的,和写法一的页面并无关联,注意⚠️这里只是展示方法)
export default connect(
  (state) => {
    const {Announcement} = state;
    return {
      Announcement
    };
    //就是这里,对应的上面的引用写法是不一样的呐,如下所示
    //let {isLoad, list, refreshState} = this.props.Announcement;
  },
  {
     getAnnouncementList, 
     clearAnnouncementListContent, 
     setAnnouncementListRefreshState
}
)(Announcement);
  1. 嗯是的基本这样就结束了哈,等我精进了再来补充哈

需要注意的几个地方:

export  default connect(
  (state)=>({
    status: state.homepage.status
  }),
  (dispatch)=>({
    homepage : ()=>dispatch(mainAction.mainIndex())
  })
)(Main);

在页面中的connect方法里面:state和dispatch:return的是一个纯对象


export function mainIndex(status) {
  return{
    type:types.MAIN_DATA_INDEX,
    status
  }
}

虽然xxxAction中return的status来自redux但是也要在函数里面传入参数status


const status = {
  status: '您已经登录了哦',
  user: 'Linth',
  account: '1314'
}

export default function homepage(state = status,action){
  switch (action.type){
    case types.MAIN_DATA_INDEX:
      state.status = '欢迎回来'
      return {
        ...state
      };
      break;
    default:
      return state;
  }
}

⚠️注意xxxReducer中return 的state前面要加上...就像上面这段代码展示的这样。

本文参考文章:
React Native集成Redux框架讲解与应用
react-native项目中从零开始使用redux

上一篇下一篇

猜你喜欢

热点阅读