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

ldld 2018-04-09 原文

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

   在开发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)


1.问题如下:随便在一个js工具类里面获取store之后,再store.dispatch(actions),改变了状态后页面无法自动更新?只能在用页面组件connect自动注入到props里面的dispatch改变的状态才能自动更新页面?

2.代码如下

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。

 


  

 

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

 

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

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

  1. Vue和React有什么区别,优劣?我到底应该选择哪谁?

      前端开发框架从最开始的jquery时代,到后来backbone,angular1,再到现在vue和reac […]...

  2. redux 的概述

    redux 的概述 随着 javascript 单页应用的不断发展,javascript 需要管理比以往都要多 […]...

  3. 五分钟学习React(四):什么是JSX

    JSX,即javscript XML,是js内定义的一套XML语法。目前是使用babel作为JSX的编译器。这 […]...

  4. React Native之离线缓存框架设计

    1.为什么要离线缓存? 宏观上来说: 提升用户体验: 我们要为用户提供流畅的APP操作体验,但我们无法保证所有 […]...

  5. React引领未来用户界面——心莱科技内部直播分享会

      视频地址(请点开链接观看视频)https://v.qq.com/x/page/l08427ukdjo.ht […]...

  6. 从 html 实现一个 react

    从 html 实现一个 react...

  7. React 深入系列5:事件处理

    文:徐超,《React进阶之路》作者 授权发布,转载请注明作者及出处 React 深入系列5:事件处理 Rea […]...

  8. vue任意关系组件通信与跨组件监听状态 vue-communication

    大家好!我是木瓜太香! 众所周知,组件式开发方式给我们带来了方便,不过也引入了新的问题,组件之间的数据就像被一 […]...

随机推荐

  1. 免费数据库(SQLite、Berkeley DB、PostgreSQL、MySQL、Firebird、mSQL、MSDE、DB2 Express-C、Oracle XE)

    SQLite数据库是中小站点CMS的最佳选择 SQLite 是一个类似Access的轻量级数据库系统,但是更小 […]...

  2. 第3章 神经网络

        上一章我们学习了感知机。关于感知机,既有好消息,也有坏消息。好消息是,即便对于复杂的函数,感知机也隐含 […]...

  3. win10下安装mysql5.7.16解压版

    1. 官网下载mysql5.7.16解压文件 2. 解压到自己的文件夹(我的是D:\software\inst […]...

  4. 远程桌面无法复制粘贴

    在远程桌面打开任务管理器,结束进程rdpclip.exe; 开始—>运行 输入rdpclip.exe,点 […]...

  5. 免费SSL证书(https网站)申请,便宜SSL https证书申请

    免费SSL证书(https网站)申请,便宜SSL https证书申请 为什么要用HTTPS 网站没有使用HTT […]...

  6. HCNA Routing&Switching之PPPoE协议

    运营商希望通过一台接入设备来连接远程的多个主机,同时接入设备能够提供访问控制和计费功能;在众多的接入技术中,把 […]...

  7. 时序图(Sequence Diagram)—UML图(六)

            时序图(Sequence Diagram)是显示对象之间交互的图,这些对象是按时间顺序排列的。 […]...

  8. 答读者问(4):inferCNV的几个问题

    1.肿瘤细胞太少怎么办? Z: 我的样本是肿瘤原发灶、淋巴结转移灶,我的淋巴结细胞恶性细胞基本都是几十个,这样 […]...

展开目录

目录导航