2018-05-24-redux

作者: 简书Boss | 来源:发表于2018-06-02 15:53 被阅读0次

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

    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

    相关文章

      网友评论

        本文标题:2018-05-24-redux

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