Ref: Redux 入门教程(三):React-Redux 的用法

组件拆分规范


使用 React-Redux,需要掌握额外的 API,并且要遵守它的组件拆分规范。

React-Redux 将所有组件分成两大类:

  • UI 组件 负责 UI 的呈现,就是conponent。
  • 容器组件 负责管理数据和逻辑,就是container。

如果一个组件既有 UI 又有业务逻辑,那怎么办?

将它拆分成下面的结构:

* 外面是一个容器组件,    ----> 前者负责与外部的通信,将数据传给后者  ----> 由 React-Redux 自动生成

* 里面包了一个UI 组件。      ----> 后者渲染出视图                                         ----> 由用户提供

connect函数


一、 UI 组件 --> 容器组件

connect方法,用于从 UI 组件生成容器组件。connect的意思,就是将这两种组件连起来。

import { connect } from 'react-redux'

const VisibleTodoList【容器组件】 = connect(mapStateToProps, mapDispatchToProps)(TodoList【UI组件】)
  • 代码解析

(1) 一个页面可能会有十个state,使用connect让我们只关注当前有使用的几个。

(2) 尾部的参数的意思:因为返回的是一个带参数的func,参见: js 用闭包实现 curry化

二、connect的两个参数

  • mapStateToProps

建立一个从 (外部的)state对象 到(UI 组件的)props对象 的映射关系。

    • 第一个参数,总是state对象
/**
* 参数state代表的是 整个网页的“状态”。
*/
const mapStateToProps = (state) => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)    // 从state算出 todos 的值 ---->
}
}

state算出 todos 的值。

const getVisibleTodos = (todos, filter) => {
switch (filter) {
case 'SHOW_ALL':
return todos
case 'SHOW_COMPLETED':
return todos.filter(t => t.completed)
case 'SHOW_ACTIVE':
return todos.filter(t => !t.completed)
default:
throw new Error('Unknown filter: ' + filter)
}
}
    • 第二个参数,代表容器组件的props对象
// 容器组件的代码
// <FilterLink filter="SHOW_ALL">
// All
// </FilterLink> const mapStateToProps = (state, ownProps) => {
return {
active: ownProps.filter === state.visibilityFilter
}
}

使用ownProps作为参数后,如果容器组件的参数发生变化,也会引发 UI 组件重新渲染。

connect方法可以省略mapStateToProps参数,那样的话,UI 组件就不会订阅Store,就是说 Store 的更新不会引起 UI 组件的更新。

  • mapDispatchToProps

建立映射:(外部的) state对象 ====>  (UI 组件的) props对象

建立映射:UI 组件的参数           ====>  store.dispatch方法

定义了哪些用户的操作应该当作 Action,传给 Store。

const mapDispatchToProps = (
dispatch,
ownProps
) => {
return {
onClick: () => {
dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: ownProps.filter
});
}
};
}

思考题:有了connect -> react-reduct,就不需要:Every listener registered with store.subscribe(listener) will now be invoked.

Provider 组件


一、原理

connect方法生成容器组件以后,需要让容器组件拿到state对象,才能生成 UI 组件的参数。

一种解决方法是将state对象作为参数,传入容器组件。但是,这样做比较麻烦,尤其是容器组件可能在很深的层级,一级级将state传下去就很麻烦。

React-Redux 提供Provider组件,可以让容器组件拿到state。其实就是在讲下图。

二、放在共享位置里

利用React组件的context属性,Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了。

import { Provider }    from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App' let store = createStore(todoApp); render(  
<Providerstore={store}>  // <----------- 这里就是重点!
<App />
</Provider>,
document.getElementById('root')
)

三、从共享位置获取

子组件就可以从context拿到store

/* 容器组件,visibleTodoList */
class VisibleTodoList extends Component {
componentDidMount() {
const { store } = this.context;
this.unsubscribe = store.subscribe(() =>
this.forceUpdate()
);
} render() {
const props = this.props;
const { store } = this.context;
const state = store.getState();
// ...
}
} VisibleTodoList.contextTypes = {
store: React.PropTypes.object
}

实例代码研究


Ref: jackielii/simplest-redux-example

Ref: redux/examples/counter/

Ref: bbandydd/serverless-client-s3   【看上去未来会有用】

--------------------------------------------------------------------------------------------

Ref: bbandydd/React_Startkit                              【代码讲解】

Ref: [線上讀書會] andy workshop 一天入魂 react-redux【五个小时~】

一、效果图

3
+-

二、代码结构

  • Redux组件拆分

从 3:34:05 / 5:14:37 开始讲解代码。

  • container 和 component 的区别

container:更新状态;从redux's state去取,与redux沟通。

component:画面如何呈现 based on props,不用redux。

Jeff: 下图可见,number & increment放在了”外面“。

三、代码分析

  • Step 1. 从Panel开始

---> main.js中的标签<Panel />

[container/Panel.js]

---> Panel组件的具体实现。

---> 前者写起来简单些。

export default Panel;
import Panel from '../'; export const Number;
import {Number} from 'Panel';
  • Step 2. 组件分离

  • Step 3. 发送动作信号

== 先提出一个疑点 ==

原始方式:状态的改变(onClick事件在panel里)

Redux方式:状态的改变要放在action中,也就是,onClick实则在this,props传来的action中。

== 创建动作 ==

视频讲解 - 4:01:40 / 5:14:37

点击按键,触发action,只是发了一个信号。如下,发了一个INCREMENT signal.

[actions/counterAction.js]

  • Step 4. 接收动作信号

== 执行动作 ==

去reducer中去验证,即:计算新状态(硬拷贝)。

状态 object + 负载 object ==> 新的 状态 object。

[reducers/counterReducer.js]

  • Step 5. 创建 store

== 合并动作 ==

创建 store,将总的reducer作为参数进行了”绑定“。

[store/configureStore.js]

  • Step 6. 两种组件的连接

视频讲解 - 4:30:46 / 5:14:37

如有没有这个参数,所有的state就全部给了Panel(contrainer角色)处理;

有这两个参数,就是”只处理“当前用到的。

export default connect(mapStateToProps, mapDispatchToProps)(Panel);

解决什么问题?

下图 line 17 为何能方便地直接获取 ”当下所需“ 的变量,这便是 connect 的功劳。

== 第一个参数 ==

line 31, 表示所有的state。return的就是其中需要用到的。

== 第二个参数 ==

line 39,相当于替代了 dispatch(counterAction)

  • Step 7. 容器直接获得 store

[main.js]

configureStore 就是 createStore() 的地方。

四、添加新功能

有了Redux框架,新功能的添加就成了体力活,这也是 Redux 框架的优势和迷人的地方。

  • 按钮UI组件添加

Btn里这个button set里,继续添加一个button。

  • 动作信号添加

注意:这里取代了dispatch(...)方法,为什么能这样呢?详见Step 6。

  • 状态更新方法添加

  • 使用“按钮UI组件”处添加

在Panel.js中 (container) 添加对应的使用方式。

[React] 13 - Redux: react-redux的更多相关文章

  1. 前端笔记之React(五)Redux深入浅出

    一.Redux整体感知 Redux是JavaScript状态管理容器,提供了可被预测状态的状态管理容器.来自于Flux思想,Facebook基于Flux思想,在2015年推出Redux库. 中文网站: ...

  2. react聊天室|react+redux仿微信聊天IM实例|react仿微信界面

    一.项目概况 基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+react-photoswipe+swiper等技术混合开 ...

  3. RxJS + Redux + React = Amazing!(译一)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...

  4. RxJS + Redux + React = Amazing!(译二)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...

  5. Flux --> Redux --> Redux React 入门

    本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...

  6. 如何在非 React 项目中使用 Redux

    本文作者:胡子大哈 原文链接:https://scriptoj.com/topic/178/如何在非-react-项目中使用-redux 转载请注明出处,保留原文链接和作者信息. 目录 1.前言 2. ...

  7. 【前端】react学习阶段总结,学习react、react-router与redux的这些事儿

    前言 借用阮一峰的一句话:真正学会 React 是一个漫长的过程. 这句话在我接触react深入以后,更有感触了.整个react体系都是全新的,最初做简单的应用,仅仅使用react-tools打包js ...

  8. 如何优雅地在React项目中使用Redux

    前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与 ...

  9. Flux --> Redux --> Redux React 基础实例教程

    本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...

  10. 【转】浅谈React、Flux 与 Redux

    本文转自<浅谈React.Flux 与 Redux>,转载请注明出处. React React 是一个 View 层的框架,用来渲染视图,它主要做几件事情: 组件化 利用 props 形成 ...

随机推荐

  1. Python 将图片转化为 HTML 页面

    最近在 GitHub 看到一个挺有意思的 Python 程序(img2html: Convert a image to HTML). 它能将图片的每个像素用文字代替,最后生成一个HTML文档,在浏览器 ...

  2. js获取本机id

    var hostname = location.hostname; window.location.href="http://"+hostname+":8080/zhib ...

  3. 转:甲骨文发布大数据解决方案 含最新版NoSQL数据库

    原文出处: http://www.searchdatabase.com.cn/showcontent_88247.htm 以下是部分节选: 最新发布的大数据创新成果包括: Oracle Big Dat ...

  4. CNUTCon2017全球运维技术大会(持续更新中) - 斯达克学院 - 实战驱动的 IT 教育平台 - Powered By EduSoho

    CNUTCon2017全球运维技术大会(持续更新中) - 斯达克学院 - 实战驱动的 IT 教育平台 - Powered By EduSoho   https://new.stuq.org/cours ...

  5. ALSA学习资料

    一.内核文档  Linux Sound Subsystem Documentation 二.一些API 1.snd_pcm_period_elapsed 2.snd_pcm_lib_buffer_by ...

  6. CDH:cdh5环境搭建

    安装环境三台centos7 vmw: cdh- 192.168.0.141 [主节点] cdh- 192.168.0.142 [从节点] cdh- 192.168.0.143 [从节点] 1)[各节点 ...

  7. MDX Cookbook 04 - 在集合中实现 NOT IN 逻辑 (Minus, Except, Filter 等符号和函数的使用)

    有时需要从一些查询结果里排除掉一些成员,当然平常情况下可以通过 MDX 查询中的 WHERE 条件即 Slicer 切片来完成,同样的这里显示的是如何在切片中排除掉一些成员. 先看这一个查询 - , ...

  8. Java字节码 小结

    Reference javap 基本使用方法 深入理解java字节码 从Java代码到字节码 Java字节码.class文件案例分析 字节码 核心概念 Class文件是8位字节流,按字节对齐.之所以称 ...

  9. 多线程本地图片载入演示样例【OpenCV】【Pthread】

    Pthread barrier的简单使用演示样例: C++代码例如以下: // ThreadingLoadImages.cpp : 定义控制台应用程序的入口点. // #include "s ...

  10. JVM内存模型、指令重排、内存屏障概念解析(转载)

    在高并发模型中,无是面对物理机SMP系统模型,还是面对像JVM的虚拟机多线程并发内存模型,指令重排(编译器.运行时)和内存屏障都是非常重要的概念,因此,搞清楚这些概念和原理很重要.否则,你很难搞清楚哪 ...