Redux应用单一的store原则案例详解

ldld 2018-04-09 原文

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

  1. 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()

  1. import { createStore } from 'redux'
  2. import todoApp from './reducers'
  3. let store = createStore(todoApp)

createStore() 的第二个参数是可选的, 用于设置 state 初始状态。这对开发同构应用时非常有用,服务器端 redux 应用的 state 结构可以与客户端保持一致, 那么客户端可以将从网络接收到的服务端 state 直接用于本地数据初始化。

  1. let store = createStore(todoApp, window.STATE_FROM_SERVER)
  1.  
  1.  
  1. 1.问题如下:随便在一个js工具类里面获取store之后,再store.dispatchactions),改变了状态后页面无法自动更新?只能在用页面组件connect自动注入到props里面的dispatch改变的状态才能自动更新页面?
  2. 2.代码如下
  3. Home 页面组件:
  4. class Home extends Component{
  5. constructor(props){
  6. super(props);
  7. this.goUser = this.goUser.bind(this)
  8. }
  9. goUser() {
  10. let {dispatch} = this.props;
  11. // 通过注入的dispatch对象调用就正常,能触发页面自动更新
  12. **dispatch(setDialogState({showDialog: true}));
  13. // 通过工具类就不行,状态改变后无法触发页面更新
  14. utils.setDialogState({showDialog: true});
  15. this.props.history.push('/user')
  16. }
  17. render() {
  18. return (
  19. <div>
  20. <h3>home</h3>
  21. <button onClick={this.goUser}>去用户中心页面</button>
  22. </div>
  23. )
  24. }
  25. }
  26. export default connect()(Home);

  27. ======utils.js文件如下:
  28. import storeConfigure from '../store';
  29. import {setDialogState} from '../actions';
  30. const appStore = storeConfigure()
  31. export default {
  32. setDialogState: function(data){
  33. appStore.dispatch(setDialogState(data))
  34. }
  35. }
  36. user.js页面组件
  37. import React,{Component} from 'react';
  38. import Dialog from './Dialog';
  39. import { connect } from 'react-redux'
  40. class User extends Component{
  41. constructor(props){
  42. super(props);
  43. }
  44. componentWillMount() {
  45. alert('componentWillMount user')
  46. }
  47. componentWillReceiveProps(nextProps){
  48. alert('componentWillReceiveProps user')
  49. }
  50. render() {
  51. return (
  52. <div>
  53. <h3>user</h3>
  54. <Dialog show={this.props.showDialog}/>
  55. </div>
  56. )
  57. }
  58. }
  59. const mapStateToProps = function(state) {
  60. return {
  61. showDialog: state.app.showDialog
  62. }
  63. }
  64. export default connect(mapStateToProps)(User);

  65. ======reducers文件夹下的app分块的js内容如下
  66. import * as types from '../actions/actionType'
  67. let initialState = {
  68. showDialog: false
  69. }
  70. export function app(state=initialState,action){
  71. switch(action.type){
  72. case types.SET_DIALOG_STATE:
  73. return Object.assign({},initialState,action.data);
  74. break;
  75. default :
  76. return Object.assign({},initialState,action.data);
  77. break;
  78. }
  79. }
  80. store.js如下:
  81. import {createStore} from 'redux';
  82. import reducers from '../reducers';
  83. export default function configureStore(initialState) {
  84. let store = createStore(reducers, initialState,
  85. // 触发 redux-devtools
  86. window.devToolsExtension ? window.devToolsExtension() : undefined
  87. );
  88. return store;
  89. }


    ====全局App.js入口文件
import storeConfigure from ‘./store’;
export default () => (
<Provider store={storeConfigure()}>
<App/>
</Provider>
)
  1.  
  1.  

上面问题哪里不对了?。

问题就出在这里:

  1. configureStore()在你的react项目里,只能出现一次,记住只能出现一次!!!
    如果出现了多次,就是违背了单一store原则。哪怕你状态也改了,页面就是不会自动更新,因为页面注入的状态来自于另一个store

 

 

下面就是你的store的写法,推荐的写法跟不推荐的写法。

 

  1. import {createStore, applyMiddleware } from 'redux';
  2. import thunkMiddleware from 'redux-thunk'
  3. import { createLogger } from 'redux-logger'
  4. import reducers from '../reducers';
  5. const loggerMiddleware = createLogger()
  6. // 不推荐的写法
  7. export default function configureStore(initialState) {
  8. let store = createStore(reducers, initialState,
  9. applyMiddleware(thunkMiddleware, loggerMiddleware),
  10. // 触发 redux-devtools
  11. window.devToolsExtension ? window.devToolsExtension() : undefined
  12. );
  13. console.log(store)
  14. return store;
  15. }
  16. // 推荐的写法
  17. function configureStore(initialState) {
  18. let store = createStore(reducers, initialState,
  19. applyMiddleware(thunkMiddleware, loggerMiddleware),
  20. // 触发 redux-devtools
  21. window.devToolsExtension ? window.devToolsExtension() : undefined
  22. );
  23. console.log(store)
  24. return store;
  25. }
  26. const appStore = configureStore();
  27. export default appStore;

 

当然,这问题主要使用的场景就是在非react组件里面通过store.dispatch(action)来改变状态。

比如建立websocket的事件监听,或者一个普通uitls.js里面的。

有点类似于JavaScript原生的addEventListener。

 

  1.  

  

 

发表于 2018-04-09 10:25 道亦有盗 阅读() 评论() 编辑 收藏

 

版权声明:本文为ldld原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ldld/p/8757846.html

Redux应用单一的store原则案例详解的更多相关文章

  1. husky+ prettier + commitlint 提交前代码检查和提交信息规范

        一、安装相关的包 npm install -D husky npm install -D lint-s […]...

  2. [RN] React Native 使用 阿里巴巴 矢量图标库 iconfont

     React Native 使用 阿里巴巴 矢量图标库 iconfont 文接上文: React Native […]...

  3. React.js 新手教程

    React.js 新手教程 正如你能从标题猜到的,这篇文章的目标是给那些有很少编程经验的读者的。比如,像我这样 […]...

  4. React中的数据双向传递

    数据从父组件到子组件 一、将数据从父组件传递到子组件,参数传递过程时,注意父组件和子组件中各自属性的名称 父组 […]...

  5. react axios 跨域访问一个或多个域名

    react axios 跨域访问一个或多个域名 1.react + axios 跨域访问一个域名 配置非常简单 […]...

  6. React 为什么要把事件挂载到 document 上 & 事件机制源码分析

    前言 我们都知道 React 组件绑定事件的本质是代理到 document 上,然而面试被问到,为什么要这么设 […]...

  7. 虚拟DOM与diff算法

    虚拟DOM与diff算法 虚拟DOM 在DOM操作中哪怕我们的数据,发生了一丢丢的变化,也会被强制重建整预DO […]...

  8. React-redux: React.js 和 Redux 架构的结合

    通过Redux 架构理解我们了解到 Redux 架构的 store、action、reducers 这些基本概 […]...

随机推荐

  1. labview使用了报表模块,在生成exe时需要添加以下内容,否则打包后不能开启excel功能

    1.在你的安装目录下找到文件夹(D:\Program Files (x86)\National Instrum […]...

  2. 爬虫之 BeautifulSoup与Xpath

    知识预览 BeautifulSoup xpath   BeautifulSoup 一 简介 简单来说,Beau […]...

  3. 设计模式之模板方法模式(一)

    设计模式之模板方法模式(一) 学习了前面的朋友都知道,目前为止,我们的议题都是绕着封装转;我们已经封装了对象创 […]...

  4. 特殊格式文件(视频、声音等) 在数据库中的存储方式

    问题描述:一般网站,对于用户上传的图片、视频、声音等特殊格式的数据是以本地文件的形式存储,然后把相应URL路径 […]...

  5. 照虎画猫写自己的Spring——自定义注解

    Fairy已经实现的功能 读取XML格式配置文件,解析得到Bean 读取JSON格式配置文件,解析得到Bean […]...

  6. 多线程学习总结之 线程池

    前言:    本文基于jdk1.8。 前段时间换工作,面试时候每次都会问线程的问题,自己对多线程方面的知识没有 […]...

  7. J2EE的13种核心技术简介

      Java最初是在浏览器和客户端机器中粉墨登场的。当时,很多人质疑它是否适合做服务器端的开发。现在,随着对J […]...

  8. Cow Marathon(树的直径)

    传送门 Cow Marathon Time Limit: 2000MS   Memory Limit: 300 […]...