首先,這裏是我的HOC:如何正確記憶mapDispatchToProps?
export default function connectField({
nameProp = 'name',
valueProp = 'value',
dispatchProp = 'dispatch'
}: ConnectOptions) {
return compose(
getContext(contextTypes),
connect((state, ownProps) => {
const path = [namespace,...getPath(ownProps),...toPath(ownProps[nameProp])];
const value = getOr('', path, state);
return {
[valueProp]: value
};
}, (dispatch,ownProps) => { // <----------- mapDispatchToProps
const path = [...getPath(ownProps),...toPath(ownProps[nameProp])];
return {
[dispatchProp]: value => dispatch({type: ActionTypes.Change, payload: {path, value}})
};
}, (stateProps, dispatchProps, {[FIELD_PATH]: _, ...ownProps}) => {
return {...stateProps, ...dispatchProps, ...ownProps};
}, {
areMergedPropsEqual: (a,b) => {
let eq = shallowEqual(a,b);
console.log('areMergedPropsEqual',a,b,eq);
return eq;
},
}),
withContext(contextTypes, props => {
return {[FIELD_PATH]: [...getPath(props), props[nameProp]]};
}),
);
}
在中間有我的mapDispatchToProps
。這導致areMergedPropsEqual
每次都會返回false,因爲它每次都會創建一個新的動作創建器。
我無法弄清楚如何memoize的該位:
value => dispatch({type: ActionTypes.Change, payload: {path, value}})
,這樣我每次得到相同的功能實例。
關於「per-instance memoization」,這是我想要的,但我無法完全理解我應該在這裏做的正面或反面的一些注意事項in the docs。
要清楚,我知道如何記憶一個函數。但是,我不希望使用具有無限歷史的大緩存。這是不必要的內存消耗。我只需要像how reselect does it那樣的緩存大小1。問題在於我不能直接在connectField
內創建「選擇器」,因爲它仍然會創建一個共享實例 - 即所有「連接的字段」將共享相同的緩存,並且它們將相互覆蓋,從而否定好處。它必須是每個組件實例。 這是特定於React-Redux的connect
方法。它有一個語法,以便您可以在正確的位置創建選擇器,並且每個實例只會運行一次。我只是在解密API時遇到問題 - 他們是否期望一個函數返回一個返回對象的函數?或者是一個帶有名稱作爲鍵和函數作爲值的對象?那個函數返回什麼?即文檔不清楚mapDispatchToProps
選項所接受的所有不同變化。
更多的相關信息@KyleRichardson更緊密地閱讀'mapDispatchToProps'。它需要一個「對象*或*函數」。然後,如果函數需要一個或兩個參數,它會再次執行一些不同的操作。然後在「高級場景」下,它說該函數可以*返回一個函數。所以呃...我想我想用一個參數傳遞一個函數並返回一個返回對象的函數。沒關係,我會搗鼓它,直到我弄明白爲止。 – mpen
我很抱歉沒有找到你想要的東西。我現在瞭解這個問題,這是一個非常有趣的問題。仍然在想它......如果你想出一個解決方案,請你更新一下,以便我可以查看想法:) –