RN开发系列<8>--Redux(1)入门篇

1.Redux的基本用法

前言

说明: 本文只针对移动端的Redux的基本用法进行描述。

  1. 希望这一篇文章,就能帮助你搞定redux的基本用法,甚至不用再去查阅其他文档。
  2. 因为我个人脑子比较笨,查阅了很多文档,看了不少视频资料才理解了。

2. 原理阐述(个人根据对官方文档理解的阐述)

  1. 关键词 store、action、reducer
  2. store是全局唯一的(在服务端可能有多个,但是我们在移动开发中,只有一个),它的作用是用来存储数据。
  3. action,翻译过来就是“动作,行动”的意思。 在我们这里,我们可以理解为对一种行动的描述,包括名字,要做的事情,参数等。
  4. reducer,翻译过来就是“减速器”的意思,个人理解为缓冲者可能比较妥当。
    (1)意思是,当有人发送一个action,会给到reducer来处理,或者作为一个缓冲地带,来进行一些数据处理。
    (2)处理后的数据会存储到store中,而且这是唯一可以改变store中的数据方法。
  5. 数据的使用
    (1)get方法,在UI界面中,数据源通过get方法获取
    (2)set方法,在这里没有直接的set方法,要修改数据,通过dispatch来set (dispatch翻译过来就是发送,派遣,邮寄的意思,我们可以理解为发送快递的方式)
    (3)这里通过dispatch发送的包裹,就是action(这里有一些我们想修改的数据相关内容)
  • 数据流向图(单一数据流向)
    在这里插入图片描述

3.脑海里大概有个上面的数据流向图即可,先看下面的代码(最好自己也写一遍,会加深印象,有助于理解)

  • 文件目录结构如下
    在这里插入图片描述
一. 我们先搭建一个简单的界面(View1–index.js)
import React, { Component } from 'react';
import {
    Button,
    Text,
    View,
    StyleSheet
} from 'react-native';

import { connect } from 'react-redux';
import * as uiAction from '../Redux/action/uiActions';

class Home extends Component {

    constructor(props) {
        super(props);

        this.state = {
            name: "张三",
            age: 18
        }
    }

    render() {
        return (
            <View style = {styles.container}>
                <Text>Hello, my name is { this.state.name },I'm {this.state.age} years old</Text>
                <Button 
                    title='增加年龄'
                    onPress={() => {
                    
                    }}
                />
                <Button 
                    title='减少年龄'
                    onPress={() => {
                    
                    }}
                />
                <Button 
                    title='修改姓名'
                    onPress={() => {
                        
                    }}
                />
            </View>
        )
    }
}

export default Home

const styles = StyleSheet.create({
    container: {
        justifyContent: 'center',
        alignItems: 'center',
        flex: 1
    }
})

在这里插入图片描述

二. 我们想做的事情很简单
  1. 点击增加或减少年龄,修改界面的年龄显示
  2. 点击修改名字,修改界面的名字显示
  • 那么我们如何通过Redux来实现呢?我们分为几个步骤。
三.Redux的使用步骤(本文核心内容)

开始之前,我们导入依赖库

一次性导入依赖库:
yarn add immutable \
react-redux \
redux \
redux-logger \
redux-promise-middleware \
redux-thunk

1.step one
  • 创建action、reducer、store
    (1) 我们创建actionType.js文件
import { ActionType } from 'redux-promise-middleware';

/*
* 编程规范建议:
* 1. 我们的每个action大类,个人觉得以ActionXX来开头命名,
*    使用的时候更能体现见名知意。
* 2. 里面对具体某个action,个人觉得以K开头,更能区分代表是具体action的key值
*/
export const actionType = {
    ActionUI: {  
        KaddAge:                 "addAge",
        KdecrementAge:           "decrementAge",
        KmodifyName:             "modifyName"
    }
}

(2) 我们创建uiActions.js文件

import { actionType } from "./actionType";

/**
 * 通常,根据action类型来命名函数
 */

/*
* type:表示是action的具体类型,我们可以直接使用我们上个actionType
* payload: 表示参数,也是外面传过来的参数
* 在这里,addAge函数,就是dispatch发送的包裹了
*/
export function addAge(age) {
    return {
        type: actionType.ActionUI.KaddAge,
        payload: age
    }
}

export function decrementAge(age) {
    return {
        type: actionType.ActionUI.KdecrementAge,
        payload: age
    }
}

export function modifyName(name) {
    return {
        type: actionType.ActionUI.KmodifyName,
        payload: name
    }
}

(3) 创建所有action的入口函数,index.js,我们这里暂时没有创建

export * from './uiAction'
export * from './xxAction'  // 如果有别的action,可以统一放到这里
export * from './xxxAction'
2.step two

(1)创建uiReducer.js文件

import { actionType } from "../action/actionType";
import { fromJS } from "immutable";

/**
 * 初始状态,不可变的,这里的state的的key,都是在UI界面中的state可以直接调用的
 * 比如:界面一个文本的名字内容,显示什么,就是直接用这里的myName
 */

function initialState() {
    return fromJS({
        myName: "张三",
        myAge: 18
    });
  }

/**
* 这里为了代码的简洁性、可读性、维护性、解耦性
* 我们不要写成switch语句,否则一个函数的行数很容易超过50行
* 个人不建议一个函数的行数超过50行
* 
*  我们这里根据prototype来定义多个函数,只是参数的类型不同
*  有点像C++里的函数重载
*/
export default function reducer(state = initialState(), action) {
    if (typeof reducer.prototype[action.type] === 'function') {
        return reducer.prototype[action.type](state, action);
    } else {
        return state;
    }
}

reducer.prototype[actionType.ActionUI.KaddAge] = (state, action) => {
    return state.set('myAge', action.payload);
}

reducer.prototype[actionType.ActionUI.KdecrementAge] = (state, action) => {
    return state.set('myAge', action.payload);
}

reducer.prototype[actionType.ActionUI.KmodifyName] = (state, action) => {
    return state.set('myName', action.payload);
}

(2)创建reducer的入口函数,index.js

import ui from './uiReducer';
import otherReducer from './otherReducer'; // 假如还有其他reducer
import { combineReducers } from 'redux';

export default combineReducers({
    ui,
    otherReducer // 如果还有其他reducer,就这样类似往里面添加
});
3.step three

创建store,也是唯一的store

import { applyMiddleware, createStore } from "redux";
import { createLogger } from "redux-logger";
import thunk from "redux-thunk";
import promise from "redux-promise-middleware";
import reducer from '../reducer';

// 分为调试环境 和 release环境,调试环境就有log日志
const middleware = __DEV__ ?
                   applyMiddleware(promise, thunk, createLogger())
                   :
                   applyMiddleware(promise, thunk)


export default createStore(reducer, middleware)
  • 到此为止,我们已经完成了80%了。如果能看到这里,提前恭喜一下你!
4.step four
  • 现在需要把redux和UI界面串联起来
  • 对于下面的没有使用过redux的UI界面,我们开始改造
class Home extends Component {

    constructor(props) {
        super(props);

        this.state = {
            name: "张三",
            age: 18
        }
    }

    render() {
        return (
            <View style = {styles.container}>
                 {...}
            </View>
            )
     }
}
export default Home

(1)去掉constructor
(2)导入connect,导入把export default Home改为:

import { connect } from 'react-redux';

export default connect((state) => {
    return {
       	 person: state.ui
        };
  })(Home);

(3) 用Provider包裹整个APP

import React from 'react';
import { Provider } from 'react-redux';
import store from './smallDemo/Redux/store/store';

const ReduxApp = () => (
    <Provider store={store}>
        <App />
    </Provider>
)
   

AppRegistry.registerComponent(appName, () => ReduxApp);

(4) dispatch的使用方法

   render() {
        return (
            <View style = {styles.container}>
                <Text>Hello, my name is { this.props.person.get('myName') },I'm {this.props.person.get('myAge')} years old</Text>
                <Button 
                    title='增加年龄'
                    onPress={() => {
                        this.props.dispatch(
                            uiAction.addAge(this.props.person.get('myAge') + 20)
                        )
                    }}
                />
                <Button 
                    title='减少年龄'
                    onPress={() => {
                        this.props.dispatch(
                            uiAction.addAge(this.props.person.get('myAge') - 10)
                        )
                    }}
                />
                <Button 
                    title='修改姓名'
                    onPress={() => {
                        this.props.dispatch(
                            uiAction.modifyName("zhangsan")
                        )
                    }}
                />
            </View>
        )
    }
  • 到此为止,我们已经阐述完了整个redux的基本使用方法
  • end~ Thanks!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值