首先,这是我的HOC:
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 ,因为它每次都会创建一个新的动作创建者。
我无法弄清楚如何记住这一点:
value => dispatch({type: ActionTypes.Change, payload: {path, value}})
这样我每次都会返回相同的函数实例。
关于“每个实例的记忆化”有一些注意事项in the docs这是我想要的,但我不能完全理解我应该在这里做的事情。
要清楚,我知道如何记忆功能。但是,我不想使用具有无限历史的大缓存。这是不必要的内存消耗。我只需要像how reselect does it一样的缓存大小1。问题是我不能直接在connectField
内创建“选择器”,因为它仍会创建一个共享实例 - 即,所有“连接字段”将共享相同的缓存,它们将相互覆盖,否定利益。它必须是每个组件实例。 这是针对React-Redux的connect
方法。它有一个语法,以便您可以在正确的位置创建选择器,并且每个实例只会运行一次。我只是在解密API时遇到问题 - 他们是否期望一个函数返回一个返回一个对象的函数?或者一个对象具有作为键的键和作为值的函数?这个函数返回什么?即,文档不清楚mapDispatchToProps
选项接受的所有不同变体。
答案 0 :(得分:0)
如果您已经拥有lodash
,则可以使用memoize
函数将任何函数转换为memoized函数。这个memoized函数将计算给定参数的返回值,然后每次提供相同的参数时返回相同的返回值。
您可以像这样使用它:
import { memoize } from 'lodash'
const makeChangeDispatcher = memoize( (dispatch, path) =>
value => dispatch({type: ActionTypes.Change, payload: {path, value}})
)
...
(dispatch,ownProps) => { // <----------- mapDispatchToProps
const path = [...getPath(ownProps),...toPath(ownProps[nameProp])];
return {
[dispatchProp]: makeChangeDispatcher(dispatch, path)
};
}
...
上看到更多信息