我有一个由列表呈现的项目列表,如下所示:
items.map(item => (
<ListItem
item={item}
updates={updates[item.id]}
{/** other props like deleting loading*/}
/>
));
请注意,这里的item不是传递给动作创建者函数的内容,ListItem 是一个容器,它将改变这一点。
我的项目容器有一个优化的 mapStateToProps(它返回一个函数,而不是一个对象):
const mapDispatchToProps = {
updateItem,
//others
}
const mapStateToProps = () => {
//create momoized state creator
const memoizedStateCreator = createMemoized();
return (unused, { item, updates }) =>
//use memoized state creator
memoizedStateCreator(item, updates);
};
在我单击以保存项目时的项目中,我有这样的内容:
<button onclick={updateItem(item)}
我想把它改成
<button onclick={updateItem}
为此,我可以使用mergeProps但这会导致 Item(Item 函数)的渲染被调用,即使没有任何改变,因为我总是返回一个新的引用作为 props。它也会导致对结果进行 shadow DOM 比较(而不是会跳过那个的纯组件)
MergeProps 不能使用工厂函数(如 mapStateToProps)进行优化,我可以在其中创建记忆函数。
const mergeProps = (stateProps, dispatchProps) => ({
...stateProps,
...dispatchProps,
updateItem: () =>
stateProps.updateItem(stateProps.item),
});
一种方法是根本不使用 mergeProps 而是使用包装函数:
const wrapper = props =>
ListItem({
...props,
updateItem: () => props.updateItem(props.item),
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(memo(wrapper));
我的问题是;有没有办法用 mergeProps 做到这一点,而不必将我的功能组件变成类?
从 mapDispatchToProps 返回一个函数在我的情况下不起作用,因为 item 不是来自 ownProps,它来自 mapStateToProps