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。

 

 
        

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM