1.下载插件

npm install redux --savenpm install react-redux --save

2.项目结构

3.redux 适用于 多交互,多数据源,复杂程度高的工程中。

redux 必要知识

使用 redux 之前,基本的东西还是要都懂的,数据流向介绍:

Action:行为。它的作用就是将我们更新组件的 状态(state) 的每个动作抽象为一个行为,它有一个必须的参数 type,定义了 Action(行为) 的名称,其他参数可自定义。写法:

{type: 'TEST_ACTION',   // 定义Action的名称key1: 'value',...keyN: value
}

因为 Action 是个对象,所以,我们需要创建这个对象,那创建这个对象的方法叫做 ActionCreator,写法:

function testAction(key1: ?string, ..., keyN: ?string) {return {type: "TEST_ACTION",key1: key1,...keyN: keyN}
}

Reducer:reducer 的作用就是根据传入的 Action行为和旧的 state对象,返回一个新的 state ,然后组件会根据 state 刷新。当我们确定了组件的 state 对象结构 和 action 行为的时候就可以编写 reducer 中的内容。写法:

function testReducer(state, action) {let key1 = action.key1;switch(action.type) {case TEST_ACTION:return {...state,key1: key1 + '变化'};default:return state;}
};export default testReducer;

当然我们的工程中可能会有多个 reducer 的情况,通过 combineReducers 可以将多个 reducer 合成统一管理。

import { combineReducers } from 'redux';
import testReducer1 from './testReducer1';
import testReducer2 from './testReducer2';export default = combineReducers({testReducer1,testReducer2
});

Store:当 reducer 返回了新的 state 后,这个 state 怎么传到组件和存储就成了问题,redux 就是把这个状态统一放到 store 中进行管理。

import { createStore } from 'redux';
const store = createStore(reducers);

上面的代码根据 reducers 创建了一个 store方法集(它并不是一个对象),然后再 store 中提供一些方法供我们使用:

// 获取当前 state
store.getState()// 发送action,根据我们前面 注册的reducers 处理state
store.dispath(action)// 替换当前 state 中的 reducer
store.replaceReducer(nextReducer) // 添加监听
store.subscribe(listener)

注:

另外 redux 有 5个 全局方法:

(1)createStore:创建一个redux store 来存储应用中所有的state,应用中只能存在一个 store

createStore(reducer, [initialState],enhancer);

(2)combineReducers:把多个reducer函数作为value的object,合并成一个reducers函数,然后就可以通过reducers调用各个子reducer,state 对象的结构由传入的多个 reducer 的 key 决定。

combineReducers(...reducers)

(3)...middlewares:每个 middleware 接受 store 的 dispatch 和 getState 函数作为命名参数,并返回一个函数。

1.该函数会被传入被称为 next 的下一个 middleware 的 dispatch 方法,并返回一个接受 action 的新函数,这个函数可以直接调用 next(action),或者在其他需要的时刻调用,也可不调用。

2.调用链的最后一个 middleware 会接受真实的 store 的 dispatch 方法作为 next 参数,并结束调用链。所以 middleware 的函数为 ({ getState, dispatch }) => next => action。

3.返回值:一个应用了 middleware 后的 store enhancer。这个store enhancer 就是一个函数,并且需要应用到 createStore。它会返回一个应用了 middleware 的新 createStore。

(4)bindActionCreators:把 actionCreators 转曾拥有同名 keys 的对象,让 dispatch 把每个 actionCreator 包装起来,这样就可以直接调用它们。唯一使用 bindActionCreators 的场景是需要把 actionCreator 往下传到一个组件上,却不想让这个组件察觉到 redux 的存在,而且不希望把 redux store 或者 dispatch 传给它。

// actionCreators:一个 actionCreators 或 键值是 actionCreators 的对象
// dispatch:一个 dispatch 函数, 由 store 提供
bindActionCreators(actionCreators, dispatch)

返回值:一个与原对象类似的对象,只不过这个对象中的每个函数值都直接 dispatch action。如果传入的是个函数,返回的也是函数。

(5)compose(...fuctions):当需要多个 store 增强器 依次执行的时候使用它。compose 在应用常见的两个用法:

// 1
let buildStore = compose(applymiddleware(thunk)
)(createStore)// 2
let initStore = compose(applymiddleware(thunk)
)

参数1(arguments):合成多个函数。每个函数接受一个函数作为参数,然后返回一个函数。

参数2(Function):从右往左把接受到的函数合成后的终极函数。

换张图理解:

react-redux 需要知道的那些事

react-redux 使用

(1)首先,根据 redux官方文档的示例 我们可以看出官方建议我们将组件分成 containers(容器组件)、components(模块视图组件)、redux 三大块。所以我们这边文件的层级如下图所示:

adb version
adb devices

react-native init Test
cd Test
npm install --save redux
npm install --save react-redux
react-native start
react-native run-android

ipconfig
8081端口

(2)接着,我们再来完成视图部分,然后根据视图部分确定哪些需要 redux 支持,再来生成相应的 action 与 reducer 文件。

1.首先,是 Main 文件,作为我们的容器组件放到 containers 文件夹内,Main 中的内容:

Main.js

/*主页面*/
import React, { Component } from 'react';
import {StyleSheet,Text,View,TouchableOpacity,
} from 'react-native';// 引入 测试组件
import TestText from '../components/TestText'export default class Main extends Component {render() {return (<View style={styles.container}>{/* 需要改变的组件 */}<TestText />{/* 按钮 */}<TouchableOpacity><Text>改变文字按钮</Text></TouchableOpacity></View>);}
}const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#F5FCFF',},
});

那里面我们需要将 Text 作为视图组件独立出来,所以将视图组件 TestText 放到 components 文件夹中,TestText 中的内容:

TestText.js

/*测试组件*/
import React, { Component } from 'react';
import {Platform,StyleSheet,Text,View
} from 'react-native';export default class TestText extends Component {render() {return (<Text>Welcome to React Native</Text>);}
}

(3)视图部分我们搭建完成,那么我们接着就是确定需要哪些 action(行为),那前面提到了,我们是要点击按钮的时候让文字发生改变,也就是说我们当前需要一个改变文字的行为,那我们就将这个行为命名为 CHANGE_TEXT,那么我们需要初始化这个 action 这个对象,也就是前面我们提到的 action creator:

action.js

/*** 步骤一* 行为 action*/// 定义行为名称
export const CHANGE_TEXT = 'CHANGE_TEXT';// 初始化 CHANGE_TEXT 对象
export const changeText = (text) => { // 接收test参数return {type: CHANGE_TEXT, // 名称text // 参数 默认值}
};

(4)action 文件配置完毕后,我们就可以根据需求来编写 reducer 文件了,reducer 文件就是起到更新 state 的作用嘛,所以我们将改变 文字 的逻辑放到这里,当reducer 匹配到当前的点击行为为 CHANGE_TEXT 时,就执行相应的操作,返回一个新的 state 给我们使用,如果匹配不到,那么就默认返回一个不变的新 state:

reducer.js

/*** 步骤二* 操作* 通过reducer操作action(根据action行为创建reducer文件)*//*** 引入 action* CHANGE_TEXT 类型(行为名称)* changeText 值*/
import { CHANGE_TEXT, changeText } from '../action/action';/*** 创建 reducer* 根据名称判断是哪一个行为* state = changeText('welcome to React Native') 初始化state*/
const mainReducer = (state = changeText('welcome to React Native'), action) => {/*** state 不能直接改变* 定义newState 接收state的值*/const newState = state;const text = action.text;// 判断 action 类型switch (action.type) {case CHANGE_TEXT:return {// 返回所有的newState...newState,text: '改变了' + text};default:return {...newState,text:state.text}}
};// 输出口
export default mainReducer;

(5)配置完 action 和 reducer 两个文件后,紧接着我们就可以根据 reducer 来初始化 store 了:

store.js

/*** 步骤三* 初始化 store*/
// 引入 reducer(操作)
import Reducer from '../reducer/reducer';
// 获取redux中的初始化方法 createStore
import { createStore } from 'redux';// 输出
export default () => {// 根据 reducer 初始化 storeconst store = createStore(Reducer);return store;
}

(6)redux 的东西已经都配置完成了,接着就剩下使用了,所以接下来要解决的问题就是怎么发送行为,怎么接收 state(状态),上面提到了,store 其实是个方法集,我们的 发送行为 和 接收状态 方法都在 store 中,所以只要拿到 store,所以只要拿到 store 就能进行这两个操作。

(7)那怎么拿到 store 呢?在官方文档中,清楚地告诉我们,Provider 的任务就是将 store 传给 connect,而 connect 的作用是将我们的组件进行第二次包装,将操作数据的函数和数据的状态包装到 props 中,所以,首先,我们需要对我们的 Main 文件进行第一次包装,我们再新建一个 index 文件来对 Main 文件进行包装:

Index.js

/*** 容器组件* 入口文件*/
import React, { Component } from 'react';// 引用外部文件
import { Provider } from 'react-redux';
import Main from './Main';
import configureStore from '../redux/store/store';// 调用 store 文件中的 mainReducer常量中保存的方法
const store = configureStore();
// 定义根组件
export default class Root extends Component {render() {return(// 第一层包装,为了让 main 能够拿到 store<Provider store={store}><Main /></Provider>)}
}

(8)包装完成后,我们的 Main 文件就可以获得 store 了,那接着就是进行第二次包装了,通过 connect 生成新组件:

Main.js

/*主页面*/
import React, { Component } from 'react';
import {StyleSheet,Text,View,TouchableOpacity,
} from 'react-native';// 引入 测试组件
import TestText from '../components/TestText'
/*** 获取 react-redux的 connect() 方法* 注:使组件层级中的 connect() 方法能够得到 redux store*/
import { connect } from 'react-redux';
// 获取 action行为的值
// import { CHANGE_TEXT } from '../redux/action/action';
import { changeText } from '../redux/action/action';class Main extends Component {render() {// 通过 props 拿到保存的 onChangeTextconst { onChangeText } = this.props;return (<View style={styles.container}>{/* 需要改变的组件 */}{/* 将父组件(Main)的props,传递给子组件(TestText)*/}<TestText {...this.props} />{/* 按钮 */}<TouchableOpacity// 设置按钮点击事件onPress={onChangeText}><Text>改变文字按钮</Text></TouchableOpacity></View>);}
}const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#F5FCFF',},
});/************ 初始化 ************/
// 获取 state 变化
const mapStateToProps = (state) => {return {// 获取 state 变化value: state.text,}
};// 发送行为
const mapDispatchToProps = (dispatch) => {return {// 发送行为// onChangeText: () => dispatch({type: CHANGE_TEXT}),onChangeText: () => dispatch(changeText('外部传值')),}
};/*** 通过 connect() 方法 对Main组件进行第二层包装* 进行第二层包装,生成的新组件拥有 接收和发送 数据的能力* mapStateToProps 获取状态的函数* mapDispatchToProps 发送行为的函数*/
export default connect(mapStateToProps, mapDispatchToProps)(Main);

(9)到这里,我们的 新组件 就能够收发数据了,那怎么接收和发送呢,别急,我们接着就来完成 mapStateToProps(更新回调) 和 mapDispatchToProps(发送行为) 两个方法。首先,我们需要通过 mapDispatchToProps 来发送行为,然后通过 mapStateToProps 来监听 state 的变化,这边我们需要发送的行为 type 是 CHANGE_TEXT,当发送行为之后,reducer 就会去匹配 行为的类型,进行相应操作:

// 发送行为
const mapDispatchToProps = (dispatch) => {return {onChangeText: () => dispatch(changeText('外部传值')),}
};

(10)当 reducer 接收到我们触发的 行为 并进行一系列处理后,最终会返回一个新的 state,那么 就会自动调用 mapStateToProps 来告诉系统,state 被操作了,那么我们就可以通过 mapStateToProps 来获取 state 状态:

// 获取 state 变化
const mapStateToProps = (state) => {return {value: state.text,}
};

(11)那么接下来我们 怎么改变文字 呢?前面提到,connect 作用就是生成一个新的组件,新的组件的 props 中包含了数据获取和操作数据的函数,所以我们需要让 子组件拿到容器组件中的 props,然后在 子组件 中通过 props 就可以拿到上面 定义的 value 和 onChangeText:

TestText.js

/*测试组件*/
import React, { Component } from 'react';
import {StyleSheet,Text,View
} from 'react-native';export default class TestText extends Component {render() {// 获取 props 中的 valueconst { value } = this.props;return (// 根据 value 改变内部文字<Text>{value}</Text>);}
}

(12)效果图

注:转载 http://blog.csdn.net/yeshaojian/article/details/70599572

.

react-native 之 redux 与 react-redux相关推荐

  1. 利用 Create React Native App 快速创建 React Native 应用

    React Native App简介 打开React Native官方文档你会发现,在Getting Started章节下新添加一个Quick Start Tab页.Quick Start是在v0.4 ...

  2. React Native开发之必备React基础

    为了帮助大家快速上手React Native开发,在这本节中将向大家介绍开发React Native所需要的一些React必备基础知识. 概述 本节课将从React的特点.如何使用React.JSX语 ...

  3. React Native 的未来与React Hooks

    近期和一些朋友聊到了 React-Native 的官方重构状态,而刚好近期发布的 0.59.x 系列版本中,上层设计出现了比较大的调整,结合体验之后的状态,就想聊聊 React-Native 的现状. ...

  4. React Native —— App

    使用 React Native 作为 app 框架,Redux 作为数据层,因此我们需要选用一些支持性的技术和工具: 开源的 Parse Server 做数据存储 - 运行在 Node.js 上. F ...

  5. React Native指南

    React本机 (React Native) React Native is a cross-platform framework for building mobile applications t ...

  6. 这是我最喜欢的使用React Native创建生产级应用程序的技巧

    Trust me when I say this, React Native is hard. And it's not the usual hard of what we think hard is ...

  7. 如何在React Native中构建项目并管理静态资源

    by Khoa Pham 通过Khoa Pham 如何在React Native中构建项目并管理静态资源 (How to structure your project and manage stati ...

  8. React Native初探

    React Native初探 转自:博客园 叶小钗  前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP ...

  9. iOS新知识学习之React Native开发工具集

    本文整理了React Native iOS开发过程中有用的工具.服务.测试.库以及网站等. 工具 你可以选择不同的开发环境:DECO.EXPO或者你可以使用Nuclide+Atom,目前我使用EXPO ...

  10. 一文学会React Native(保姆级教程) 持续更新

    React Native 官网 如果react基础有些遗忘,可以打开React官网查看 介绍 React Native 是一个使用React和应用平台的原生功能来构建 Android 和 iOS 应用 ...

最新文章

  1. 基于点云曲率的图像特征提取方法
  2. Spring Cloud Alibaba基础教程:几种服务消费方式(RestTemplate、WebClient、Feign)
  3. Mint系统使用介绍,Mint系统安装,在Mint系统上搭建GPU环境,在Mint系统上安装Pycharm、Anaconda等软件,在Mint系统上安装cuda和cudnn
  4. 机器人出魔切还是三相_工业机器人常见故障和修理方法
  5. yii2 html 跳转,阐述在Yii2上实现跳转提示页
  6. SharePoint 2010 沙盒开发
  7. 全球活跃开发者不足 1500 万,业余爱好者和学生仅占四分之一
  8. 计算机将在1分钟重启,Win10开机经常提示将在一分钟后自动重启如何处理
  9. 应用随机过程张波商豪_应用随机过程张波课后答案
  10. 51单片机c语言怎么定义引脚,80C51单片机引脚功能图解
  11. 载银纳米TiO2/壳聚糖水凝胶/pH/GSH响应羧甲基壳聚糖水凝胶和纳米凝胶的制备
  12. 《商业银行会计》--概述
  13. 计算机二级Python笔记——第一部分
  14. Mac系统查看端口占用的进程
  15. 网站数据采集的10个经典方法
  16. vm磁盘映射 不能启动_iOS 启动优化之Clang插桩实现二进制重排
  17. iphone上安装android系统,如何在iPhone上安装Android操作系统?
  18. 日期问题合集(时令、时区)
  19. 彻底终结敲诈者 360独家推出“文档卫士”
  20. 关于指数函数等价无穷小的小发现!

热门文章

  1. Angular2 管道
  2. 一个面试题关于变量的生命周期
  3. hbaseRowkey设计
  4. Kafka常用运维操作命令
  5. php缓存静态化设计,PHP使用OB缓存实现静态化功能示例
  6. java mvc 源码分析_SpringMVC 源码解读笔记
  7. 弹出框之对话框和提示框,可共用代码
  8. Access数据库通过ODBC导出到Oracle的两个小问题ora-24801\Ora-01401
  9. Atom 备份神器 —— Sync Settings
  10. 任务管理器使用不了-灰色