首先,这里是我的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
我很抱歉没有找到你想要的东西。我现在了解这个问题,这是一个非常有趣的问题。仍然在想它......如果你想出一个解决方案,请你更新一下,以便我可以查看想法:) –