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)的更多相关文章

  1. React:快速上手(4)——掌握Redux(1)

    React:快速上手(4)——掌握Redux 引入Redux 混乱的state管理 随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状 ...

  2. React:快速上手(7)——使用中间件实现异步操作

    React:快速上手(7)——使用中间件实现异步操作 本文参考链接:Stack Overflow redux-thunk 我们使用store.dispath进行派发时,只能传递一个普通对象进去,如下: ...

  3. 官方 React 快速上手脚手架 create-react-app

    此文简单讲解了官方 React 快速上手脚手架的安装与介绍. 1. React 快速上手脚手架 create-react-app 为了快速地进行构建使用 React 的项目,FaceBook 官方发布 ...

  4. React:快速上手(6)——掌握React Router

    React:快速上手(6)——掌握React Router 引入Router 安装 npm install react-router-dom 基础组件 React Router中有三种类型的组件:路由 ...

  5. React:快速上手(3)——列表渲染

    React:快速上手(3)——列表渲染 使用map循环数组 了解一些ES6 ES6, 全称 ECMAScript 6.0 ,是 JaveScript 的下一个版本标准,2015.06 发版.ES6 主 ...

  6. React:快速上手(2)——组件通信

    React:快速上手(2)——组件通信 向父组件传递数据 父组件可以通过设置子组件的props属性进行向子组件传值,同时也可以传递一个回调函数,来获取到子组件内部的数据. 效果演示 子组件是输入框,父 ...

  7. React:快速上手(1)——基础知识

    React:快速上手(1)——基础知识 React(有时叫React.js或ReactJS)是一个为数据提供渲染为HTML视图的开源JavaScript库,用于构建用户界面. JSX.元素及渲染 1. ...

  8. React:快速上手(8)——前后端分离的跨域访问与会话保持

    React:快速上手(8)——前后端分离的跨域访问与会话保持 跨域访问 跨域是指从一个域名的网页去请求另一个域名的资源.比如从http://www.baidu.com/ 页面去请求http://www ...

  9. react快速上手二(使用JSX语法)

    前提: 下载依赖,配置 cnpm i babel-preset-react -D JSX语法的本质: 还是以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代 ...

随机推荐

  1. impala+kudu

    [impala建表]kudu的表必须有主键,作为分区的字段需排在其他字段前面. [range分区](不推荐)CREATE TABLE KUDU_WATER_HISTORY ( id STRING, y ...

  2. 自己编写Android Studio插件 别停留在用的程度了(转载)

    转自:自己编写Android Studio插件 别停留在用的程度了 1概述 相信大家在使用Android Studio的时候,或多或少的会使用一些插件,适当的配合插件可以帮助我们提升一定的开发效率,更 ...

  3. 在同一台电脑上添加多个ssh key

    1.创建新的ssh key: ssh-keygen -t rsa -C "your_email@email.com" 然后让你输入新的文件名称,这里设置为new # 设置名称为En ...

  4. hibernate中的java对象有几种状态,其相互关系如何(区别和相互转换)。

    hibernate中的java对象有几种状态,其相互关系如何(区别和相互转换). 解答:在Hibernate中,对象有三种状态:临时状态.持久状态和游离状态. 临时状态:当new一个实体对象后,这个对 ...

  5. (转)java volatile关键字

    转自:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 参考:http://blog.csdn.net/imzoer/ar ...

  6. java调用oracle函数

    /** * 调用函数取得数据表的ID值 * @param tableName 表名 * @return * @throws SQLException */ public String callFun( ...

  7. js的实例方法和静态方法分析

    var Person=function(){}; Person.say=function(){ console.log('I am a Person,I can say.') }; Person.pr ...

  8. Jmeter_远程启动 I

    Jmeter 是Java 应用,对于CPU和内存的消耗比较大,因此,当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至会引起JAVA内存溢出错误. 其实,Jmeter的 ...

  9. SpringMVC如何接收json数据

    请求头:Content-Type=application/json数据如: {"mobile":"12345678912","smsContent&q ...

  10. Parrot Linux国内源

    China USTC (University of Science and Technology of China and USTCLUG) - Hefei University 1 Gbps for ...