在开发reac单页面应用的时候,页面的展示逻辑跟数据状态的关系管理变得越来越复杂,redux很好的解决这个问题。废话不多说,直接先上官网api链接。

http://cn.redux.js.org/index.html

 官方文档跟你把概念性的东西讲解的很清楚的,怎么串联起来使用,就得多采坑才行。下面就是我踩的一个坑。 react-redux非组件里面store.dispatch(action)页面不更新的问题。主要是关于store的:

在前面的章节中,我们学会了使用 action 来描述“发生了什么”,和使用 reducers 来根据 action 更新 state 的用法。

Store 就是把它们联系到一起的对象。Store 有以下职责:

再次强调一下 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入口文件
import storeConfigure from './store';
export default () => (
<Provider store={storeConfigure()}>
<App/>
</Provider>
)
 

上面问题哪里不对了?。

问题就出在这里:

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原则案例详解的更多相关文章

  1. spring的IOC,DI及案例详解

    一:spring的基本特征 Spring是一个非常活跃的开源框架:它是一个基于Core来架构多层JavaEE系统的框架,它的主要目的是简化企业开发.Spring以一种非侵入式的方式来管理你的代码,Sp ...

  2. 深入浅出 spring-data-elasticsearch - 基本案例详解(三

    『  风云说:能分享自己职位的知识的领导是个好领导. 』运行环境:JDK 7 或 8,Maven 3.0+技术栈:SpringBoot 1.5+, Spring Data Elasticsearch ...

  3. ​ 用一个开发案例详解Oracle临时表

    ​ 用一个开发案例详解Oracle临时表 2016-11-14 bisal ITPUB  一.开发需求  最近有一个开发需求,大致需要先使用主表,或主表和几张子表关联查询出ID(主键)及一些主表字段 ...

  4. http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误)

    http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误) 一.总结 服务器内部错误可能是服务器中代码运行的时候的语法错误或者逻辑错误 二.http500:服务器内部错误案例详解 只是一 ...

  5. spss进行判别分析步骤_spss判别分析结果解释_spss判别分析案例详解

    spss进行判别分析步骤_spss判别分析结果解释_spss判别分析案例详解 1.Discriminant Analysis判别分析主对话框 如图 1-1 所示 图 1-1 Discriminant ...

  6. str_replace函数的使用规则和案例详解

    str_replace函数的使用规则和案例详解 str_replace函数的简单调用: <?php $str = '苹果很好吃.'; //请将变量$str中的苹果替换成香蕉 $strg = st ...

  7. 第7.20节 案例详解:Python抽象类之真实子类

    第7.20节 案例详解:Python抽象类之真实子类 上节介绍了Python抽象基类相关概念,并介绍了抽象基类实现真实子类的步骤和语法,本节结合一个案例进一步详细介绍. 一.    案例说明 本节定义 ...

  8. 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法

    第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一.    案例说明 本节定义了类Sta ...

  9. 第7.16节 案例详解:Python中classmethod定义的类方法

    第7.16节  案例详解:Python中classmethod定义的类方法 上节介绍了类方法定义的语法以及各种使用的场景,本节结合上节的知识具体举例说明相关内容. 一.    案例说明 本节定义的一个 ...

随机推荐

  1. 关于LINUX里面查找,替换,编辑的一些用法

    1.GREP查找(如果只是查找文件当中是否有该内容的话) grep -rn "hello,world!" * "hello,world!":表示要查找的字段 * ...

  2. k60详细引脚功能截图

  3. SpringBoot工作机制

    1:前言 回顾探索Spring框架 1.spring ioc IoC其实有两种方式,一种就是DI,而另一种是DL,即Dependency Lookup(依赖查找),前者是当前软件实体被动接受其依赖的其 ...

  4. eclipse报错排解

    一.解决eclipse中git插件中的cannot open git-upload-pack问题 有时候在eclipse上使用插件egit向github或者osc上同步代码时,有时候会发现出现cann ...

  5. 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面

    一.创建脚本工具并执行初始迁移 在本节中,您将使用包管理控制台(PMC)来更新数据库: •添加VisualStudio Web代码生成包.这个包是运行脚本引擎所必需的. • 执行Add-Migrati ...

  6. npm scripts 使用指南

    转载自:http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html Node 开发离不开 npm,而脚本功能是 npm 最强大.最常用的功能之一. ...

  7. 【Python】 上下文管理器和contextlib

    上下文管理器 一直对python中的上下文管理比较迷惑,趁着今天研究SQLAlchemy顺便看了一下,感觉稍微清楚了一点.http://www.cnblogs.com/chenny7/p/421344 ...

  8. java中的并发工具类

    在jdk的并发包里提供了几个非常有用的并发工具类.CountDownLatdch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线 ...

  9. docker 学习之一:docker 安装

    核心概念1. 镜像是一个只读的模板类似于安装系统用到的那个iso文件我们通过镜像来完成各种应用的部署. 2. docker容器镜像类似于操作系统而容器类似于虚拟机本身.它可以被启动.开始.停止.删除等 ...

  10. spring boot 1.x.x 到 spring boot 2.x.x 的那些变化

    spring boot1 到 spring boot2的配置变化很大,迁移项目到spring boot2过程中发现以下变化 1.java 的 redis 配置添加了属性jedis 旧版 spring: ...