【发布时间】:2018-01-11 18:07:03
【问题描述】:
首先,这是我的 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 时遇到了麻烦——他们是否期望一个函数返回一个返回对象的函数?还是一个以 propnames 作为键、函数作为值的对象?该函数返回什么?即,文档并不清楚 mapDispatchToProps 选项接受的所有不同变体。
【问题讨论】:
-
@KyleRichardson 仔细阅读
mapDispatchToProps。它需要一个“对象或函数”。然后,如果函数采用一两个参数,它会再次执行不同的操作。然后在“高级场景”下,它说函数可以也返回一个函数。所以呃......我想我想给它传递一个带有一个参数的函数并返回一个返回一个对象的函数。没关系,等我弄明白为止。 -
我很抱歉偏离了您所寻找的内容。我现在明白了这个问题,这是一个非常有趣的问题。还在考虑...如果您提出解决方案,请您更新,以便我可以查看想法:)
标签: reactjs redux react-redux memoization