zoukankan      html  css  js  c++  java
  • 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。

    
    

      

  • 相关阅读:
    3.5星|津巴多《时间的悖论》:未来导向的人更有可能取得个人的成功,但帮助他人的可能性更小
    成功的销售必须在失败时也能快乐:4星|《哈佛商业评论》2018年第4期
    被取代的金融工作岗位越来越多:3星|《被人工智能操控的金融业》
    比特币和区块链是泡沫,但是短期内不会破:4星|《财经》2018年第7期
    点赞是当代可卡因:3星|《欲罢不能:刷屏时代如何摆脱行为上瘾》
    如何使用GetManifestResourceStream
    隐藏光标与获得光标2----获得光标所在的控件
    端口是否使用
    是否联网以及热点问题
    注册表操作
  • 原文地址:https://www.cnblogs.com/ldld/p/8757846.html
Copyright © 2011-2022 走看看