React:快速上手(5)——掌握Redux(2)
React:快速上手(5)——掌握Redux(2)
本文部分内容参考阮一峰的Redux教程。
React-Redux原理
React-Redux运行机制
我觉得这张图清楚地描述React-Redux的运行机制:
React-Redux将组件划分为两类,第一类是UI组件:
- 只负责 UI 的呈现,不带有任何业务逻辑
- 没有状态(即不使用
this.state这个变量) - 所有数据都由参数(
this.props)提供 - 不使用任何 Redux 的 API
比如,我们的实例计数器就是一个UI组件,我们只写了UI的呈现规则,并且所有数据都是由this.props提供:
class Counter extends React.Component{
render() {
const{onSubmitClick,value} = this.props;
return(
<div>
<span>{value}</span>
<button onClick={onSubmitClick}>提交</button>
</div>
)
}
}
第二类组件是容器组件:
- 负责管理数据和业务逻辑,不负责 UI 的呈现
- 带有内部状态
- 使用 Redux 的 API
不过,React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成。
Connect负责从UI组件生成容器组件
如下,一行语句,我们就将获得由UI组件得到的容器组件
const CounterApp = connect(mapStateToProps,mapDispatchToProps)(Counter)
这个函数由两个参数,mapStateToProps和mapDispatchToProps构成。它们主要定义业务逻辑,前者负责输入逻辑,即容器组件如何将state转换为props交给UI组件,来供容器组件进行UI渲染。后者负责输出逻辑,用来建立 UI 组件的参数到store.dispatch方法的映射。
如下,我们定义mapStateToProps,它将state中的count字段取出映射到value属性,然后交给UI组件:
function mapStateToProps(state) {
return{
value:state.count
}
}
然后,我们定义mapDispatchToProps,他将store.dispatch方法映射到onSubmitClick属性上,这样UI组件通过props.onSubmitClick,就可以间接调用store.dispatch,实现状态更新。
function mapDispatchToProps(dispatch) {
return{
onSubmitClick:()=>dispatch({type:'INCREASE'})
}
}
<Provider>组件
connect方法生成容器组件以后,需要让容器组件拿到state对象,才能生成 UI 组件的参数。一种解决方法是将state对象作为参数,传入容器组件。但是,这样做比较麻烦,尤其是容器组件可能在很深的层级,一级级将state传下去就很麻烦。
React-Redux 提供Provider组件,可以让容器组件拿到state。
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'
let store = createStore(todoApp);
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
上面代码中,Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了。
一个完整的计数器例子
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider, connect } from 'react-redux'
// React component
class Counter extends Component {
render() {
const { value, onIncreaseClick } = this.props
return (
<div>
<span>{value}</span>
<button onClick={onIncreaseClick}>Increase</button>
</div>
)
}
}
Counter.propTypes = {
value: PropTypes.number.isRequired,
onIncreaseClick: PropTypes.func.isRequired
}
// Action
const increaseAction = { type: 'increase' }
// Reducer
function counter(state = { count: 0 }, action) {
const count = state.count
switch (action.type) {
case 'increase':
return { count: count + 1 }
default:
return state
}
}
// Store
const store = createStore(counter)
// Map Redux state to component props
function mapStateToProps(state) {
return {
value: state.count
}
}
// Map Redux actions to component props
function mapDispatchToProps(dispatch) {
return {
onIncreaseClick: () => dispatch(increaseAction)
}
}
// Connected Component
const App = connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
React:快速上手(5)——掌握Redux(2)的更多相关文章
- React:快速上手(4)——掌握Redux(1)
React:快速上手(4)——掌握Redux 引入Redux 混乱的state管理 随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状 ...
- React:快速上手(7)——使用中间件实现异步操作
React:快速上手(7)——使用中间件实现异步操作 本文参考链接:Stack Overflow redux-thunk 我们使用store.dispath进行派发时,只能传递一个普通对象进去,如下: ...
- 官方 React 快速上手脚手架 create-react-app
此文简单讲解了官方 React 快速上手脚手架的安装与介绍. 1. React 快速上手脚手架 create-react-app 为了快速地进行构建使用 React 的项目,FaceBook 官方发布 ...
- React:快速上手(6)——掌握React Router
React:快速上手(6)——掌握React Router 引入Router 安装 npm install react-router-dom 基础组件 React Router中有三种类型的组件:路由 ...
- React:快速上手(3)——列表渲染
React:快速上手(3)——列表渲染 使用map循环数组 了解一些ES6 ES6, 全称 ECMAScript 6.0 ,是 JaveScript 的下一个版本标准,2015.06 发版.ES6 主 ...
- React:快速上手(2)——组件通信
React:快速上手(2)——组件通信 向父组件传递数据 父组件可以通过设置子组件的props属性进行向子组件传值,同时也可以传递一个回调函数,来获取到子组件内部的数据. 效果演示 子组件是输入框,父 ...
- React:快速上手(1)——基础知识
React:快速上手(1)——基础知识 React(有时叫React.js或ReactJS)是一个为数据提供渲染为HTML视图的开源JavaScript库,用于构建用户界面. JSX.元素及渲染 1. ...
- React:快速上手(8)——前后端分离的跨域访问与会话保持
React:快速上手(8)——前后端分离的跨域访问与会话保持 跨域访问 跨域是指从一个域名的网页去请求另一个域名的资源.比如从http://www.baidu.com/ 页面去请求http://www ...
- react快速上手二(使用JSX语法)
前提: 下载依赖,配置 cnpm i babel-preset-react -D JSX语法的本质: 还是以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代 ...
随机推荐
- idea编译修改jdk版本
由于项目需要,需要修改jdk的版本为1.8,这里记录一下修改的地方 1,项目的jdk版本 右键点击项目-> open module setting ->project,然后如图所示 2,在 ...
- C语言 百炼成钢25
/* 题目61:编写一个名为removestring的函数,该函数用于从一个字符串中删除一定量的字符. 该函数接受三个参数: 第1参数代表源字符串 第2参数代表需要删除字符的起始位置(位置从0开始) ...
- CocosCreate 与 Netty 开发斗地主 (一步一步开发)
CocosCreate 与 Netty 开发斗地主 开发此教程的目的是为了教会大家基本的使用Netty,通过一个小例子来教会大家制作斗地主游戏服务器,采用WebSocket方式! 目前正在制作阶段, ...
- jQuery DataTables添加自定义多个搜索条件
效果如下: 一.在前台页面定义输入搜索条件的文本框 <div class="ibox-tools"> <span>年度</span> @Html ...
- 【BZOJ】3399: [Usaco2009 Mar]Sand Castle城堡(贪心)
http://www.lydsy.com/JudgeOnline/problem.php?id=3399 贪心就是将两组排序,然后直接模拟即可.. 如果我们用a去匹配一个绝对值和它差不多的值,那么去匹 ...
- android发送邮件
众所周知,在Android中调用其他程序进行相关处理,几乎都是使用的Intent,所以,Email也不例外. 在Android中,调用Email有三种类型的Intent: Intent.ACT ...
- CodeFirst中DbContext动态添加DbSet
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...
- delphi连接sql server数据库,并根据sql语句查询出数据显示--初级
需要用到四个组件,分别为: 1.ADOConnection1 设置Connectionstring属性(连接串),loginPrompt属性控制是否连接记住了密码: 2.ADOQuery1 设置Con ...
- windows平台 - 0基础学习node.js(一)
首先得明白node.js做什么用的: 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. Nod ...
- 【BZOJ1511】[POI2006]OKR-Periods of Words next数组
[BZOJ1511][POI2006]OKR-Periods of Words Description 一个串是有限个小写字符的序列,特别的,一个空序列也可以是一个串. 一个串P是串A的前缀, 当且仅 ...
