Redux应用单一的store原则案例详解
在开发reac单页面应用的时候,页面的展示逻辑跟数据状态的关系管理变得越来越复杂,redux很好的解决这个问题。废话不多说,直接先上官网api链接。
http://cn.redux.js.org/index.html
官方文档跟你把概念性的东西讲解的很清楚的,怎么串联起来使用,就得多采坑才行。下面就是我踩的一个坑。 react-redux非组件里面store.dispatch(action)页面不更新的问题。主要是关于store的:
在前面的章节中,我们学会了使用 action 来描述“发生了什么”,和使用 reducers 来根据 action 更新 state 的用法。
Store 就是把它们联系到一起的对象。Store 有以下职责:
- 维持应用的 state;
- 提供
getState()方法获取 state;- 提供
dispatch(action)方法更新 state;- 通过
subscribe(listener)注册监听器;- 通过
subscribe(listener)返回的函数注销监听器。再次强调一下 Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用 reducer 组合而不是创建多个 store。
根据已有的 reducer 来创建 store 是非常容易的。在前一个章节中,我们使用
combineReducers()将多个 reducer 合并成为一个。现在我们将其导入,并传递createStore()。import { createStore } from 'redux'
import todoApp from './reducers'
let store = createStore(todoApp)
createStore()的第二个参数是可选的, 用于设置 state 初始状态。这对开发同构应用时非常有用,服务器端 redux 应用的 state 结构可以与客户端保持一致, 那么客户端可以将从网络接收到的服务端 state 直接用于本地数据初始化。let store = createStore(todoApp, window.STATE_FROM_SERVER)
.问题如下:随便在一个js工具类里面获取store之后,再store.dispatch(actions),改变了状态后页面无法自动更新?只能在用页面组件connect自动注入到props里面的dispatch改变的状态才能自动更新页面?
.代码如下
Home 页面组件:
class Home extends Component{
constructor(props){
super(props);
this.goUser = this.goUser.bind(this)
}
goUser() {
let {dispatch} = this.props;
// 通过注入的dispatch对象调用就正常,能触发页面自动更新
**dispatch(setDialogState({showDialog: true}));
// 通过工具类就不行,状态改变后无法触发页面更新
utils.setDialogState({showDialog: true});
this.props.history.push('/user')
}
render() {
return (
<div>
<h3>home</h3>
<button onClick={this.goUser}>去用户中心页面</button>
</div>
)
}
}
export default connect()(Home);
======utils.js文件如下:
import storeConfigure from '../store';
import {setDialogState} from '../actions';
const appStore = storeConfigure()
export default {
setDialogState: function(data){
appStore.dispatch(setDialogState(data))
}
}
user.js页面组件
import React,{Component} from 'react';
import Dialog from './Dialog';
import { connect } from 'react-redux'
class User extends Component{
constructor(props){
super(props);
}
componentWillMount() {
alert('componentWillMount user')
}
componentWillReceiveProps(nextProps){
alert('componentWillReceiveProps user')
}
render() {
return (
<div>
<h3>user</h3>
<Dialog show={this.props.showDialog}/>
</div>
)
}
}
const mapStateToProps = function(state) {
return {
showDialog: state.app.showDialog
}
}
export default connect(mapStateToProps)(User);
======reducers文件夹下的app分块的js内容如下
import * as types from '../actions/actionType'
let initialState = {
showDialog: false
}
export function app(state=initialState,action){
switch(action.type){
case types.SET_DIALOG_STATE:
return Object.assign({},initialState,action.data);
break;
default :
return Object.assign({},initialState,action.data);
break;
}
}
store.js如下:
import {createStore} from 'redux';
import reducers from '../reducers';
export default function configureStore(initialState) {
let store = createStore(reducers, initialState,
// 触发 redux-devtools
window.devToolsExtension ? window.devToolsExtension() : undefined
);
return store;
}
====全局App.js入口文件
上面问题哪里不对了?。
问题就出在这里:
configureStore()在你的react项目里,只能出现一次,记住只能出现一次!!!
如果出现了多次,就是违背了单一store原则。哪怕你状态也改了,页面就是不会自动更新,因为页面注入的状态来自于另一个store。
下面就是你的store的写法,推荐的写法跟不推荐的写法。
import {createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk'
import { createLogger } from 'redux-logger'
import reducers from '../reducers';
const loggerMiddleware = createLogger()
// 不推荐的写法
export default function configureStore(initialState) {
let store = createStore(reducers, initialState,
applyMiddleware(thunkMiddleware, loggerMiddleware),
// 触发 redux-devtools
window.devToolsExtension ? window.devToolsExtension() : undefined
);
console.log(store)
return store;
}
// 推荐的写法
function configureStore(initialState) {
let store = createStore(reducers, initialState,
applyMiddleware(thunkMiddleware, loggerMiddleware),
// 触发 redux-devtools
window.devToolsExtension ? window.devToolsExtension() : undefined
);
console.log(store)
return store;
}
const appStore = configureStore();
export default appStore;
当然,这问题主要使用的场景就是在非react组件里面通过store.dispatch(action)来改变状态。
比如建立websocket的事件监听,或者一个普通uitls.js里面的。
有点类似于JavaScript原生的addEventListener。
Redux应用单一的store原则案例详解的更多相关文章
- spring的IOC,DI及案例详解
一:spring的基本特征 Spring是一个非常活跃的开源框架:它是一个基于Core来架构多层JavaEE系统的框架,它的主要目的是简化企业开发.Spring以一种非侵入式的方式来管理你的代码,Sp ...
- 深入浅出 spring-data-elasticsearch - 基本案例详解(三
『 风云说:能分享自己职位的知识的领导是个好领导. 』运行环境:JDK 7 或 8,Maven 3.0+技术栈:SpringBoot 1.5+, Spring Data Elasticsearch ...
- 用一个开发案例详解Oracle临时表
用一个开发案例详解Oracle临时表 2016-11-14 bisal ITPUB  一.开发需求 最近有一个开发需求,大致需要先使用主表,或主表和几张子表关联查询出ID(主键)及一些主表字段 ...
- http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误)
http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误) 一.总结 服务器内部错误可能是服务器中代码运行的时候的语法错误或者逻辑错误 二.http500:服务器内部错误案例详解 只是一 ...
- spss进行判别分析步骤_spss判别分析结果解释_spss判别分析案例详解
spss进行判别分析步骤_spss判别分析结果解释_spss判别分析案例详解 1.Discriminant Analysis判别分析主对话框 如图 1-1 所示 图 1-1 Discriminant ...
- str_replace函数的使用规则和案例详解
str_replace函数的使用规则和案例详解 str_replace函数的简单调用: <?php $str = '苹果很好吃.'; //请将变量$str中的苹果替换成香蕉 $strg = st ...
- 第7.20节 案例详解:Python抽象类之真实子类
第7.20节 案例详解:Python抽象类之真实子类 上节介绍了Python抽象基类相关概念,并介绍了抽象基类实现真实子类的步骤和语法,本节结合一个案例进一步详细介绍. 一. 案例说明 本节定义 ...
- 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法
第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一. 案例说明 本节定义了类Sta ...
- 第7.16节 案例详解:Python中classmethod定义的类方法
第7.16节 案例详解:Python中classmethod定义的类方法 上节介绍了类方法定义的语法以及各种使用的场景,本节结合上节的知识具体举例说明相关内容. 一. 案例说明 本节定义的一个 ...
随机推荐
- Fiddler抓取https设置及其原理
iddler抓取https设置及其原理 2018-02-02 目录 1 HTTPS握手过程2 Fiddler抓取HTTPS过程3 Fiddler抓取HTTPS设置参考 数字签名是什么? 1 HTTPS ...
- VS中使用.NET Reactor进行代码混淆
.NET Reactor相信大家都不陌生,网上使用教程也很多.但绝大多数都只介绍到软件的使用,而对于在VS中使用介绍的不多. 首先,在.NET Reactor的Help中Add In,如下图. 重启V ...
- MyBatis笔试题
1请写出Mybatis核心配置文件MyBatis-config.xml的内容? <?xml version="1.0" encoding="UTF-8"? ...
- eclipse热部署web项目
一.选中JavaEE视图 因为在普通的Java视图下,窗口下方没有server选项卡 二.双击Tomcat 注意:可能很多人当然包括我一开始的时候,都是喜欢右键Tomcat然后Add and remo ...
- JavaIO 总结
另外参考文章:http://www.ibm.com/developerworks/cn/java/j-lo-javaio/ 一. File类 file.createNewFile();file.del ...
- Python 从入门到入门基础练习十五题
**a) 6.成绩转换:编写一个学生成绩转换程序,用户输入百分制的学生成绩,成绩大于或等于60的输出"pass",否则输出"fail",成绩不四舍五入. a = ...
- leetCode:461 汉明距离
汉明距离 两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目. 给出两个整数 x 和 y,计算它们之间的汉明距离. 思路: 当看到"对应二进制位不同的位置的数目"这 ...
- Javascripte的原型链之基础讲解
一.函数对象与普通对象 var o1 = {}; var o2 =new Object(); var o3 = new f1(); function f1(){}; var f2 = function ...
- 【Python】 list & dict & str
list & dict & str 这三种类型是python中最常用的几种数据类型.他们都是序列的一种 ■ 序列通用操作 1. 分片 s[a:b] 返回序列s中从s[a]到s[b- ...
- java基础笔记(8)----接口
接口 是特殊的抽象类,纯抽象类---所有方法都是抽象方法 接口和抽象类的区别: 相同点: 编译后,会分别生成对应的.class文件 都不能创建对象(实例化),但是可以生成引用(使用多态) 不同点: 抽 ...