react redux 子组件件都要connect吗

redux中connect的使用(3)-最简单的一个傻瓜app - 简书
redux中connect的使用(3)-最简单的一个傻瓜app
在(1)中我讲了一个电灯的例子,用开关来控制等的状态的变化,现在把它用react-native/redux来实现了,比counter还要简单,只有一个状态的改变,都已经写好了,还可以作为一个框架来使用。安装了redux-logger以后,可以在按下按钮的时候实时的看到状态的变化。同时结合在UI组件中的console.log的方法,基本解决了redux调试的方法问题。在Component中导入了react-native-elements组件库。这个和bootstrap的效果类似,封装了很多的组件可以直接来使用,这个组件库可以换为native-base组件库。在组件中修改UI 完全不改变app的交互操作的逻辑。就这个简单的app就做了一下午,主要原因是一个也是初学,另外一个问题为了调试加进去了好多的console.log(),完全搞乱的出现问题的原因,但是这个坑还是值得的。主要的目的就是给需要学习redux的同学提供一个简单的教程。redux的学习也要不断的反复拿捏才行,理解以后其实觉得redux的思想其实很简单,但是要发生这个转变需要一定的时间,当然有基础的高手除外。
[github代码在这](
界面就是这么一个,有一个灯,下面有一个开关,要解决的问题就是按下按钮的操作使灯的状态发生变化,Component里面有两个文件,一个是直接在组件中操作,另外一个就是我们这里的主题,组件中操作以后,state在redux中绕了一圈以后回到组件中,组件的状态就发生了变化,这里组件和redux是分开的,在学习的时候等你体会到这种分开的情况就离理解差不多了。
要时刻注意的是流程,组件和redux的衔接1. 组件的操作是怎么在Redux中对上暗号,接上头的2.Redux中状态发生改变之后又是怎么返回的组件的
以上两点就是connect的内容,关键就在这里。
screenshot_16.png
screenshot_17.png
下面是文件的结构,稍等我放到github上去。
screenshot_15.png
下面先从视觉组件开始
先贴一下直接在组件中操作的逻辑例子
'use strict';
import React, { Component } from 'react';
AppRegistry,
StyleSheet,
} from 'react-native';
import * as lampAction from '../actions/lamp';
//import {Container, Header, Title, Content,Button } from 'native-base';
} from 'react-native-elements'
class Lamp extends Component {
constructor(props) {
super(props);
this.state = { //初始化状态
light: false
componentDidMount() {}
//组件中直接操作的函数,负责改变状态
this.setState({
light : !this.state.light //状态发生翻转
render() {
this.shut=this.shut.bind(this);
//console.log(light); //可以在组件中打印state
//light==false?(uri=' ./image/off.png'):(uri=' ./image/on.png');
var status = this.state.light==false
? require('./image/off.png')
: require('./image/on.png');
&View style={styles.container}&
&Image source={status}
style={styles.customimg}
style={styles.buttonMargin}
onPress={ this.shut}
title='开关' /&
var styles=StyleSheet.create({
//样式省略
export default L
下面是作为导入redux以后的组件代码
//Lamp/src/component/Lamp.js
'use strict';
import React, { Component } from 'react';
AppRegistry,
StyleSheet,
} from 'react-native';
SocialIcon
} from 'react-native-elements'; //导入的elements组件库
//你可以选择其他的组件库,加速开发流程。
class Lamp extends Component {
constructor(props) {
super(props);
componentDidMount() {}
render() {
//下面这一句是理解的难点,在react中组件都是在使用的时
//候,通过注入props来获取一些参数,下面这两个参数,一个是操
//作的方法名,一个是灯的状态,初学的时候很难理解这两个东西
//到底是从哪里来的。其实有点远,组件获取这两个东西的地方是
//在container文件夹中,container文件其实做的内容很少,就是
//要建立组件和Redux之间的联系,这两个东西也就是在那里注入进来的
const { switchLamp,light} = this.
console.log(light.light); //这个语句可以随时监测light的状态是
//false还是true.
//下面这个三元判断就是根据light的状态来决定加载哪一张图片
var status =light.light==false
? require('./image/off.png')
: require('./image/on.png');
&View style={styles.container}&
&Image source={status}
style={styles.customimg}/&
name='heartbeat'
type='font-awesome'
color='#f50'
//这个地方的switchLamp是函数,然而这个函数并不在这里执
//行,我在container里面吧这个函数绑定到了dispatch上
//这样,执行这个函数,绑定地就会执行一个dispatch(),dispatch的意思
//是分发,那么分发这个函数到什么地方呢?这个函数和action
//中一个函数名字是一样的,这样发生在组件中的函数动作就会和
//redux中的函数名配对了,redux就感知到了组件要干什么,所谓
//对上眼了,对上暗号了。这里我们约定好函数名只由redux中的
//action来定义,组件中直接来用,这样就不会发生错误匹配的问题
//这里的onPress函数式唯一和操作逻辑相关的地方,如果修改组
//件样式,或者更换组件,只保留这个函数就可以了,其他的都可
//样式和逻辑彻底分开了,当然这是理想化的,实际操作的是后,
//也是挺复杂的。
onPress={() =& switchLamp()} /&
var styles=StyleSheet.create({
//样式代码省略
export default L
既然上面的函数已经和Redux已经对上眼了,我们就马上看看,他们是怎么对上的
//lamp/src/containers/App.js
import { bindActionCreators } from 'redux'; //用来绑定函数和dispatch()
import { connect } from 'react-redux'; //redux和component的中间代理人
Lamp from '../components/Lamp'; //这就是上面讲的组件
* as switchLamp from '../actions/lamp'; //获取actions中
//定义的action函数,这里并不是要这些函数做什么,而是给组件一套对暗号的密码表,
//mapStateToProps,看名字就是State转变为Props,state是在
//redux中的,组件在使用的时候是通过props来获取参数的,
//所以这里有这么一个转变的过程
function mapStateToProps(state, props) {
//console.log(state);
light:state.light //这里的state比较简单,可以很复杂
//这里把方法也转为props,以供组件使用
function mapDispatchToProps(dispatch) {
//使用bindActionCreators来绑定dispatch和函数
//这是switchLamp看起来是一个函数,其实是一个对象,
//包含了actions里定义的所有函数
//组件中的函数就会自动dispatch到actions中和对应的函数想匹配,dispatch以后redux就接管了后续的逻辑操作
return bindActionCreators(switchLamp, dispatch);
//connect是我们这个系列要讲的核心,所有的内容其实都是围绕
//他,尽管这一句,但是是非常重要的,经过这么connect以后
//组件就获取了所需的方法名和props,
//connect其实是很灵活的,没有规定只能connect一次,
//所有的组件都可以用他来包装,看其他代买的时候要注意
//因为一旦程序规模变大,action里面的函数就不好一次注入了,
//在不同的组件中注入自己需要的函数和props是很好的选择。
export default connect(mapStateToProps, mapDispatchToProps)(Lamp);
组件dispatch 一个函数以后,redux就接管了后续的操作。 进入到actions中
//actions/lamp.js
export const SWITCH = 'SWITCH'; //这个常量是给reducer用的
//在redux中有几个地方可以打印state看看,但是这个文件中
//绝对不能打印state
import React, { Component } from 'react';
import {SWITCH} from '../constants/ActionTypes';//也可以在这里定义常量
//下面的这个函数和组件dispatch的函数名是一样的时候,就会执
//行操作,这个操作拿着type的类型去操作state的改变。
//你看凡是逻辑分离的地方都要对这个信号
export function switchLamp() {
type: SWITCH,
上面的type 就会和redcer匹配,reducer的作用是改变state,state对象其实就相当于一个数据库,用来存储app的所有变化。在redux中把state定义为一个?,树有各个部分,果实可以吃,叶子可以做药材,树皮可以做电缆,树干可以盖房子,树根可以做根雕。 当你要吃果实的时候只需要去摘果实就可以了,并不需要把整个树都弄到,所以需要进行过滤。 这个过程是在container中来完成的。我们的这个实例比较简单,只是一颗种子,么办法过滤。下面就看看reducer做了什么工作
//lamp/reducers/lamp.js
//先导入actiontype,这样从aciton过来的动作,reducer就知道要干什么
import { SWITCH } from '../constants/ActionTypes';
//初始化一颗树,先种下一颗种子,随着程序的变大,这棵树也变大
const initialState = {
light: false
//实际的操作就在这里了,
export default function light(state=initialState, action) {
switch (action.type) {
//进行匹配
case SWITCH: //匹配上了
light:!state.light, // 返回一个新的状态,取反就可以了
//ui 组件中就可以根据这个变化来改变状态
//有时候程序较复杂,reducer写在一起很难理解,所以就会分开
//最终会合并成一个
//lamp/reducers/index.js
import { combineReducers } from 'redux';
//import film from './film';
import light from './lamp';
const rootReducer = combineReducers({
export default rootR
组件所需要的逻辑操作就在reducers中完成了。
reducer改变的逻辑交给store,这个store其实不实际干活,而是一个发号施令的角色。所有的操作和所有的状态变化他都知道,所以我们可以在这里监控整个程序的变化,redux-logger在store里面注入就可以监视变化了
//看起来比较复杂
//这里面还注入了redux-sage这个是用来进行异步操作的逻辑
//在这里涉及不到。
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware, { END } from 'redux-saga';
import rootReducer from '../reducers/index'; 注入reducer到store
const middlewares = [];
const createLogger = require('redux-logger');
// configuring saga middleware
const sagaMiddleware = createSagaMiddleware();
middlewares.push(sagaMiddleware);
if (process.env.NODE_ENV === 'development') {
const logger = createLogger();
middlewares.push(logger);
const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore);
export default function configureStore(initialState) {
const store = createStoreWithMiddleware(rootReducer, initialState);
// install saga run
store.runSaga = sagaMiddleware.
store.close = () =& store.dispatch(END);
下面我们在返回container,reducer中改变的状态有要返回组件中 我把container的代码再粘贴一遍,但是注意这一次的container和刚开始的container实际是不同的,state发生了改变了。
//lamp/src/containers/App.js
import { bindActionCreators } from 'redux'; //用来绑定函数和dispatch()
import { connect } from 'react-redux'; //redux和component的中间代理人
Lamp from '../components/Lamp'; //这就是上面讲的组件
* as switchLamp from '../actions/lamp'; //获取actions中
//定义的action函数,这里并不是要这些函数做什么,而是给组件一套对暗号的密码表,
//mapStateToProps,看名字就是State转变为Props,state是在
//redux中的,组件在使用的时候是通过props来获取参数的,
//所以这里有这么一个转变的过程
function mapStateToProps(state, props) {
//console.log(state);
light:state.light //这里的state比较简单,可以很复杂
//这里把方法也转为props,以供组件使用
function mapDispatchToProps(dispatch) {
//使用bindActionCreators来绑定dispatch和函数
//这是switchLamp看起来是一个函数,其实是一个对象,
//包含了actions里定义的所有函数
//组件中的函数就会自动dispatch到actions中和对应的函数想匹配,dispatch以后redux就接管了后续的逻辑操作
return bindActionCreators(switchLamp, dispatch);
//connect是我们这个系列要讲的核心,所有的内容其实都是围绕
//他,尽管这一句,但是是非常重要的,经过这么connect以后
//组件就获取了所需的方法名和props,
//connect其实是很灵活的,没有规定只能connect一次,
//所有的组件都可以用他来包装,看其他代买的时候要注意
//因为一旦程序规模变大,action里面的函数就不好一次注入了,
//在不同的组件中注入自己需要的函数和props是很好的选择。
export default connect(mapStateToProps, mapDispatchToProps)(Lamp);
至此组件中的操作数据流程就完成了。
这个是比较简单的,但是redux的基本流程和框架就是这样的。我在(1)中讲了,因为组件和redux是解耦和,改变任意一个,另一个不发生变化就可以很好的工作。下面我们能不能再进一步? 灯的开关也可以换成声控的,有声音以后会延迟一段时间再灭,如果继续有声音,灯还会亮着。能实现吗?
react-native code beginnerRedux 学习笔记(一) - pepping798的专栏 - CSDN博客
Redux 学习笔记(一)
三个作用:
接受 actions
保存初始 state
处理 actions , 并更新state
containers
Redux makes the difference between containers, which are connected to the state, and components, which are dumb and stateless
连接 state 和 componetns 组件
dispatch action
react-redux 中的 connect
作用:提供两个关键模块:(通常在 container 中使用)
作用:Provider这个模块是作为整个App的容器,在你原有的App Container的基础上再包上一层,它的工作很简单,就是接受Redux的store作为props,并将其声明为context的属性之一,子组件可以在声明了contextTypes之后可以方便的通过this.context.store访问到store。不过我们的组件通常不需要这么做,将store放在context里,是为了给下面的connect用的。
作用: 这个模块是算是真正意义上连接了Redux和React,正好它的名字也叫connect。
先考虑Redux是怎么运作的:首先store中维护了一个state,我们dispatch一个action,接下来reducer根据这个action更新state。
映射到我们的React应用中,store中维护的state就是我们的app state,一个React组件作为View层,做两件事:render和响应用户操作。于是connect就是将store中的必要数据作为props传递给React组件来render,并包装action creator用于在响应用户操作时dispatch一个action。
React组件如何响应store的变化?
我们把connect返回的函数叫做Connector,它返回的是内部的一个叫Connect的组件,它在包装原有组件的基础上,还在内部监听了Redux的store的变化,为了让被它包装的组件可以响应store的变化:
为什么connect选择性的merge一些props,而不是直接将整个state传入?
通常,我们connect的是某个Container组件,它并不承载所有App state,然而我们的handler是响应所有state变化的,于是我们需要优化的是:当storeState变化的时候,仅在我们真正依赖那部分state变化时,才重新render相应的React组件,那么什么是我们真正依赖的部分?就是通过mapStateToProps和mapDispatchToProps得到的。
pure优化的是什么?
在shouldComponentUpdate中做检查,如果只有在组件自身的props改变,或者mapStateToProps的结果改变,或者是mapDispatchToProps的结果改变时shouldComponentUpdate才会返回true,检查的方式是进行进行shallowEqual的比较。
使用ES7 decorator功能来配合React ES6的写法:
state =& ({
user: state.user,
resource: state.resource
dispatch =& ({
...bindActionCreators({
loadResource: ResourceActions.load
}, dispatch)
export default class Main extends Component {
我的热门文章
即使是一小步也想与你分享解读redux中通过connect和bindActionCreators调用store的dispatch方法 | do IT
专注于web前端开发,专注于用户体验
今天看官方redux中的todomvc这个实例,找不到在哪里调用store.dispatch这个方法,最后在containers中的App.js文件中的mapDispatchToProps中发现,我看看一下他如何调用:有代码我们可以看到是调用了bindActionCreators方法把action绑定到了connect方法中,其中connect方法的作用是连接react组件和redux store,也就是说通过connect方法子组件可以获取store中的state和dispatch。感觉还是没找到在哪调用的dispatch方法,所以把注意力集中在bindActionCreators方法中,搜了下看到一些解释:bindActionCreators的作用是将一个或多个action和dispatch组合起来生成mapDispatchToProps需要生成的内容。看代码:不使用bindActionCreators时候:function mapDispatchToProps(dispatch) {
& &onIncrement: () =& dispatch(increment())
}使用时:let&actions&=&{
&&addItem:&&{
&&&&type:&types.ADD_ITEM,
bindActionCreators(actions,&dispatch);&
&@return&{addItem:&&dispatch({&type:&types.ADD_ITEM,&text&})}可以看到其实使用了bindActionCreators其实就是把多个action还是用dispatch调用,这样就知道了是在containers中的App.js中使用redux的connect方法获取store中的state数据和dispatch方法,然后action中声明好类型,然后再通过js事件去触发导出的action方法,因为在bindActionCreators方法中已经把actions和dispatch合并(相当于dispatch({type:type.ADD_ITEM, text})),这样就相当于在containers中这样调用dispatch去改变store中的数据:store.dispatch({&type:&types.ADD_ITEM,&text&})这样也就理解了redux说的state在其他地方是只读的,只有store中可以修改的概念了。
坐等站主更新~redux 三重境 - 对 redux 最佳实践的思考和总结1. 本文写在去年8月,有着我对redux最佳实践的思考和总结。
王国维的《人间词话》的三重境
古今之成大事业、大学问者,必经过三种之境界。
“昨夜西风凋碧树,独上高楼,望尽天涯路”,此第一境也;
“衣带渐宽终不悔,为伊消得人憔悴”,此第二境也;
“众里寻他千百度,蓦然回首,那人却在灯火阑珊处。”,此第三境也。
redux 基础知识和 react-redux
redux 周边生态探索
有哪些功能?(粗略介绍)
有哪些很不错的第三方库?(详细介绍)
最佳实践介绍(dva)
一: redux 基础知识和 react-redux
三个基本原则
在 React 应用中使用 Redux(react-redux)
redux 三个基本原则
整个应用只有唯一一个 Store 实例
State 只能通过触发 Action 来更改
State 的更改 必须写成纯函数(Reducer),(oldState, action) =& newState,也就是每次更改总是返回一个新的 State
redux 两个显著的特点
可预测性(Reducer 是纯函数)。
扩展性强(middleware)。
单向数据流
Actions 是 store.dispatch(action),它是每次数据改变的源头。
如果有 middleware 将先进入 middleware
Reducer 管理 state, 也就是 (oldState, action) =& newState 的集合。
当 state 改变后, View Provide 就会更改视图
连接 React (react-redux)
使用 Provider 在根组件 注入 Store
容器组件使用 connect() 方法连接 Redux
1. 使用 Provider 在根组件 注入 Store
2. 容器组件使用 connect() 方法连接 Redux
那么我们如何获取容器组件的依赖呢?
容器组件及其子组件需要的两个能力:
读数据:获取 redux 的 state
改数据:向 redux dispatch actions
mapStateToProps:从 store 的 state 里把容器组件依赖的部分 state 取出来,成为组件的 props。
mapDispatchToProps: 将特定的 dispatch 函数取出来变为 props 。
注: bindActionCreators 将 ActionCreator 和 store 的 dispatch 绑定到一起,返回一个特定的 dispatch 函数,组件调用即可触发 store.dispatch(action)
在 render 等函数里面 取出相应 props,自己使用或者传给子组件
分离容器组件和展示组件
redux 的重要思想:分离容器组件和展示组件。
在应用中,只有 最顶层组件是对 Redux 可知。
应该是“笨拙”的,是通过父组件传递的 props 来获取数据和更改数据的 dispatch,它是感知不到 redux 存在的,具有很强的复用性。
如何分辨容器组件和展示组件的思考
容器组件维护多个状态
展示组件维护极少的状态(一般是 ui 状态)
容器组件无关 ui,几乎没有 css 样式、html 标签,通过组合展示组件来构造容器组件
展示组件 ui 强相关,大量 css 和 html 标签
容器组件示例(ArticleBox 组件):
展示组件示例(Article 组件):
容器组件和展示组件对比
二: 探索阶段
探索 redux 生态
有哪些功能?(粗略介绍)
有哪些很不错的第三方库?(详细介绍)
最佳实践介绍(dva)
redux 生态
连接到其他库
开发(debug)工具
各类实用工具
计算、处理数据
异步 action
连接到其他库
react-redux
react-router-redux
redux-immutablejs
— 用最简单的方式书写异步 action creator
— 在初始化 reducer 和 action 构造器时减少样板代码
Data =& View store 的 select 方案,用于提取数据的筛选逻辑。
开发测试工具
redux-devtools — 一个使用时间旅行 UI 、热加载和 reducer 错误处理器的 action 日志工具
DevTools accepts monitor components(Custom Monitors)
Redux Logger
redux-logger — 记录所有 Redux action 和下一次 state 的日志
不错的第三方库
我这里就介绍一个第三方库
redux-action
简化 redux api
— 在初始化 reducer 和 action 构造器时减少样板代码
createAction
下图这是 createAction 的效果 (我把我博客的 actions refactor 一下,上面是简化后。)
原理就是高阶函数, createAction 返回一个函数,三: 最佳实践
google dva...第一个结果
实际上 dva 是基于现有应用架构 (redux + react-router + redux-saga 等)的一层轻量封装,没有引入任何新概念,全部代码不到 100 行。
由支付宝前端团队开发。
他们总结的 React + Redux 最佳实践
dva 的由来
(dva 基于此封装)
api 风格方面非常像 vue,并且沿袭了 vue 的简单易上手、api 简洁的特点。
关于 dva 的思考
react redux
react redux 的思想从一开始就是 开放的,海纳百川,官方给出的最佳实践是 组合式 的,根据需求、喜好的不同,会有十几种最佳实践。。。。
优点:社区异常活跃;扩展性强、非常灵活;中台组件库基于 React。
缺点:学习成本高,新手上手慢;太灵活,周边生态百花齐放,如果没有一定的约束,非常不易于团队合作。
去年开始 vue 以上手容易、api 简洁优雅出名,对于同类需求,官方给出的最佳实践几乎是唯一的。
优点:学习成本低,易上手;最佳实践统一,利于团队合作;作者非常给力,在 vue2.0 里,发布了很多特别棒的新 feature(jsx,virtual dom,服务器流式渲染); weex 扩展了 vue 在移动端的能力。
缺点:社区活跃低于 React;扩展性、灵活性差。
dva 结合了 react 和 vue 两者的优点
学习成本低,易上手
最佳实践统一,利于团队合作
社区异常活跃,扩展性强
中台 dpl 基于 React
降低了 redux 的扩展性、灵活性
对 dva 的态度
学习思想,借鉴他们的最佳实践; 持续跟进
使用? or 自己造轮子?
使用: 当其比较成熟时,对于复杂页面(尤其是单页应用)可以考虑使用。
or 自己造轮子: 借鉴学习其的特点和功能自己造轮子
<div class="like-count align-center" data-v-

我要回帖

更多关于 connect in redux 的文章

 

随机推荐