如何使用react-redux——傻瓜版
概述
之前看redux官方文档真是看得一脸懵逼,现在自认为会用了,于是来总结一下用法,供以后开发时参考,相信对其他人也有用。
不得不说,用了redux之后感觉挺爽的,有如下优点:
- 组件大多是函数组件非常方便测试。
- 免去了一层层传递props的困扰,如果想要数据,直接建一个容器组件即可,不需要对原组件做任何改动。
- 扩展性很强,有新动作的时候,只需在action.js里面添加,然后在reducer.js里面注册即可。
index.js
首先把index.js改成下面这个样子,用一个有store属性的Provider包裹。
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'
const store = createStore(todoApp)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
注意:以后添加路由,redux-thunk的时候也是在这里改。当规模大了的时候会独立出去一个root.js组件。
action.js
然后当然是注册动作了。
//有参数的动作
export const ADD_TODO = 'ADD_TODO'
export function addTodo(text) {
return { type: ADD_TODO, id: todoId++, text}
}
//没有参数的动作
export const SHOW_ALL = 'SHOW_ALL'
export function showAll() {
return { type: SHOW_ALL }
}
动作其实就是指令,告诉redux我需要进行某种改变。一般是没有参数的动作,不需要传递数据给store,另外一种是传递参数的动作,需要传递数据给store。
这里涉及到redux的一种理念,就是ui的改变不是通过各组件用它们的方法各自处理数据进行改变的,而是通过store处理数据,然后组件只负责渲染即可。这就是react是声明式框架而不是命令式框架的原因(各组件只是一种声明,并没有命令)。
reducer.js
注册动作之后,我们就有了指令了,但是store接收到了指令之后要怎么做?这就是reducer.js的功劳了。一般的reducer是类似下面这个样子的:
const post = (state = '无数据', action) => {
switch(action.type) {
case RECEIVE_POSTS:
return action.title
case RECEIVE_ING:
return action.text
case RECEIVE_ERROR:
return action.error
default:
return state
}
}
它有如下特点:
- 一个state的初始值。
- 一个switch处理action。
- 通过处理带参数或者不带参数的action,返回新的state。
从store这个层面上来说,经过了reducer之后,里面的数据得到了更新,做出了响应,它的任务全部完成了。但是从组件这个层面来说,它却又要处理这3个问题:
- 它如何拿到store里面的数据。
- 它如何发出指令(action)。
- store数据的改变怎么导致它的重新渲染。
这三个问题利用容器可以解决。
container.js
容器就是组件和store之间的中介。为什么需要容器?因为关注点分离的思想,在组件层面,我们只关注怎么渲染的,在容器层面,我们只关注数据怎么传递的。
一般的容器需要拿到store的数据,并且发出指令(action),下面的一个一般的容器的写法:
const mapStateToProps = state => ({
list: state
})
const mapDispatchToProps = dispatch => ({
toggleState: (id) => dispatch(toggleState(id))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
这样,我们就解决了前2个问题。然后,由于我们把store里面的数据通过props传递给了组件,所以如果state的相关数据更新的话,传递给组件的props也会更新,于是组件重新渲染,这就解决了第三个问题。
有时候,我们并不需要传递store里面的数据进来,只需要发布几个命令即可,这个时候只需要把mapStateToProps换成null即可,示例如下:
const mapDispatchToProps = dispatch => ({
addTodo: (text) => dispatch(addTodo(text))
})
export default connect(
null,
mapDispatchToProps
)(AddTodo)
组件
组件可以不作任何改动,只改成箭头函数就行了。如下所示:
import React from 'react'
const Posts = ({ title, nextText, nextPost }) => {
return (
<div>
<span>{ title }</span>
<button
onClick={() => {
nextText();
nextPost();
}}> next </button>
</div>
)
}
export default Posts
如何使用react-redux——傻瓜版的更多相关文章
- React+Redux实现追书神器网页版
引言 由于现在做的react-native项目没有使用到redux等框架,写了一段时间想深入学习react,有个想法想做个demo练手下,那时候其实还没想好要做哪一个类型的,也看了些动漫的,小说阅读, ...
- react+redux教程(四)undo、devtools、router
上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...
- 【原】react+redux实战
摘要:因为最近搞懂了redux的异步操作,所以觉得可以用react+redux来做一个小小的项目了,以此来加深一下印象.切记,是小小的项目,所以项目肯定是比较简单的啦,哈哈. 项目效果图如图所示:(因 ...
- react 后台(一) react + redux + react-route + webpack+ axios + antd + less
create-react-app 项目名称(项目失败,ant 的样式出不来) 项目技术栈 react + redux + react-route + webpack+ axios + less + a ...
- React Redux 与胖虎
这是一篇详尽的 React Redux 扫盲文. 对 React Redux 已经比较熟悉的同学可以直接看 <React Redux 与胖虎他妈>. 是什么 React Redux 是 R ...
- webpack+react+redux+es6开发模式
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
- react+redux教程(六)redux服务端渲染流程
今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...
- react+redux教程(五)异步、单一state树结构、componentWillReceiveProps
今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...
- react+redux官方实例TODO从最简单的入门(6)-- 完结
通过实现了增-->删-->改-->查,对react结合redux的机制差不多已经了解,那么把剩下的功能一起完成吧 全选 1.声明状态,这个是全选状态 2.action约定 3.red ...
- react+redux官方实例TODO从最简单的入门(1)-- 前言
刚进公司的时候,一点react不会,有一个需求要改,重构页面!!!完全懵逼,一点不知道怎么办!然后就去官方文档,花了一周时间,就纯react实现了页面重构,总体来说,react还是比较简单的,由于当初 ...
随机推荐
- Python 高阶函数map(),filter(),reduce()
map()函数,接收两个参数,一个是函数,一个是序列,map()把传入的函数依次作用于序列的每个元素,并把结果作为新的序列返回: aa = [1, 2, 3, 4, 5] print("ma ...
- python 的包的导入
已经写过一篇包的导入了,最近又遇到了点问题,所以想把这些再搞的明白点就又试了试 代码结构如下 在test目录下,有Admin包,home包,在home下有它的子包foo 各个文件代码如下 admins ...
- funny故事
name1 = input('请输入一个名字:') name2 = input('请输入一个名字:') vehicle = input('请输入一种车子:') print('\n上近代史的{}刚下课, ...
- [Ting's笔记Day1] Ruby on Rails练习- MacOS安装篇
千里之行,始于足下.喊了要学Ruby on Rails好久,今天终于要来迈向第一步:安装了! 一开始学习新的事物,主要就是跟着这个网页所说的步骤step by step. 很喜欢这个网页的设计流程,透 ...
- mobilenet之Depthwise +Pointwise
我们知道,mobilenet是适用于移动端的深度学习网络,主要优点是参数少.模型小.准确率相比一些传统卷积损失少等特点. mobileNet之所以这么ok,是因为引入了Depthwise +Point ...
- [转]IIS应用程序池经典模式转集成模式解决方案
经典模式和集成模式的区别: IIS7.0中的Web应用程序有两种配置形式:经典形式和集成形式. 经典形式是为了与之前的版本兼容,运用ISAPI扩展来调用ASP.NET运转库,原先运转于IIS6.0下的 ...
- 【Django】关于设置和获取cookies
def TestCookies(request): response=HttpResponse() # cookie=request.COOKIES#下面两句等cookies设置以后,才使用 # if ...
- 2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)
BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. Among ...
- [leetcode]47. Permutations全排列(给定序列有重复元素)
Given a collection of numbers that might contain duplicates, return all possible unique permutations ...
- Linux驱动之一个简单的输入子系统程序编写
的在Linux驱动之输入子系统简析已经分析过了输入子系统的构成,它是由设备层.核心层.事件层共同组成的.其中核心层提供一些设备层与事件层公用的函数,比如说注册函数.反注册函数.事件到来的处理函数等等: ...