2016-11-28 127 views
2

我想有,可以得到當前狀態做一些邏輯與它的功能,而無需通過參數的函數傳遞當前狀態。吸氣劑在終極版的行動 - 陣營本地

這裏是我的榜樣。

在我的操作文件,我有:

export const addToSearchHistory = (newSearch) => ({type: ADD_TO_SEARCH_HISTORY, newSearch}) 
export const addToCardHistory = (newCard) => ({type: ADD_TO_CARD_HISTORY, newCard}) 

再舉例來說,我想有一個「吸」功能,告訴我如果「搜索歷史」已經達到10項。因此,我所做的是:

export const searchHasMaxHistory =() => (dispatch, getState) => { 
    var state = getState() 
     search = state.search 

    return search.history == 10 ? true : false 
} 

我綁定與bindActionCreators其他的「真正的」行動這一功能:

const mapDispatchToProps = (dispatch) => { 
    return bindActionCreators({ 
    addToSearchHistory, 
    addToCardHistory, 

    searchHasMaxHistory 
    }, dispatch) 
} 

所以我會因爲任何行爲的正常訪問。它運作良好,並且完全符合我的要求。

但真正的問題是,它是反模式綁定它像一個動作,但它不返回一個動作?我可以通過這樣做遇到問題或任何問題嗎?有沒有一個「正確」的解決方案來做到這一點?

+0

mapDispatchToProps將您的函數包裝在調度調用中。如果您的動作創建者(searchHasMaxHistory)將「返回search.history == 10?true:false」,那麼將返回該返回值。 Dispatch只是用來發送一個動作(普通對象),它會改變你的應用程序的狀態。在這種情況下,它不會因爲你的減速器沒有處理動作:bool(true/false) –

回答

2

爲此,您應該通過mapStateToProps函數將您的「吸氣器」(在the docs中描述爲「選擇器」)綁定到您的組件。

// the selector (probably in your reducer file) 

export const searchHasMaxHistory = state => { 
    return state.search.history == 10 ? true : false 
} 

// in your component 

const mapStateToProps = (state) => { 
    return { 
    hasHitMaxHistory: searchHasMaxHistory(state) 
    } 
} 

const mapDispatchToProps = ... // keep the same, remove your "getter" 

export default connect(
    mapStateToProps, 
    mapDispatchToProps 
)(YourComponent) 

這種方法使得我更有意義,因爲您的組件的新道具將像預期,並引發了渲染()時,返回值的變化。

+0

是的,我聽說過「選擇器」,但是它不會在狀態改變時刷新。它似乎應該有:/ – Leon

+0

哈哈我的壞它沒有刷新,因爲我做了其他更改,它不是「鏈接」了...謝謝!你的回答看起來是最好的,因爲你談到了選擇器,如果你想用Redux的getter-like函數,這就是要走的路。 – Leon

+0

不客氣!反應減少的部分是有時候可以感覺有點太神奇。 – vgrafe

1

我看到你的目標是:

我想有功能,可以獲取當前的狀態,做 一些邏輯與它,而不必通過 參數傳遞當前狀態的功能。

但是bindActionCreators(actionCreators, dispatch)是用於另一目的。

它封裝了所有你的行動創造者與dispatch調用,這樣他們可以直接調用。

我們做事的方式hackish的,而不是爲什麼不使用我們原來store對象獲得的狀態。

爲您的store對象創建一個吸氣劑,您createStore

import { createStore } from 'redux' 
import reducer from './reducer'; 

let store = {}; 

export default function storeCreator() { 
    // ...do things 

    store = createStore(reducer); 

    // ...do more things 

    return store; 
} 

export function getStore() { 
    return store; 
} 
狀態的getter

現在:(功能):

import { getStore } from './storeCreator'; 

export function searchHasMaxHistory() { 
    const store = getStore(); 
    const state = store.getState(); 
    const search = state.search; 

    return search.history == 10 ? true : false 
} 
+1

現在這是一種反模式。你正在創建一個商店單身人士。如果你多次創建商店(不是你會的),你會覆蓋你的「商店」變量,並且getStore()會一直給你最新的單身人士。在這種情況下,您不需要storeCreator()或getStore()。只需編寫「導出默認createStore(reducer)」,每個「導入」給你同一個商店實例。 –

2

看看connect()

mapStateToProps(狀態)docs的如果有規定,組件將訂閱Redux商店更新。任何IT更新時間,mapStateToProps將被稱爲

所以,你可以寫你的connect()條款是這樣的:

function mapStateToProps(state) { 
    return { 
    searchHasMaxHistory: state.search.history === 10 
    }; 
} 
connect(mapStateToProps)(YourComponent) 

但當然,這將計算在每家商店的改變,你的新的價值。你可能不想要那個。在這種情況下,您可以定義一個單獨的函數,並在每次存儲(狀態)更改時將您的狀態綁定到它。

function isMaxHistoryReached(state) { 
    return state.search.history === 10; 
} 

function mapStateToProps(state) { 
    return { 
    searchHasMaxHistory: isMaxHistoryReached.bind(YourComponent, state) 
    }; 
} 
connect(mapStateToProps)(YourComponent) 

現在仍然在每次狀態更改時在內存中創建一個新函數,但它不會調用它。