我有一个由列表呈现的项目列表,如下所示:
items.map(item => (
<ListItem
item={item}
updates={updates[item.id]}
{/** other props like deleting loading*/}
/>
));
请注意,此处的项目不是传递给操作创建者的内容 函数,ListItem是一个可以更改此内容的容器。
我的项目容器有一个optimized 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函数),即使没有任何更改,因为我总是返回一个新的引用作为道具。这还会导致react对结果进行阴影DOM比较(而不是会跳过该结果的纯组件)
无法使用factory function(例如mapStateToProps)优化MergeProps,我可以在其中创建记忆功能。
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返回函数,因为项目不是来自ownProps,而是来自mapStateToProps
答案 0 :(得分:2)
假设requestDelete
是可以分派的动作,则应将其映射到已连接的mapDispatchToProps
组件的ListItem
中。 mapDispatchToProps
也可以是一个函数,它接收ownProps
作为具有id
的第二个参数:
const mapDispatchToProps = (dispatch, {item}}) => ({
requestDelete: () => dispatch(requestDelete(item.id)),
});
export default connect(mapStateToProps, mapDispatchToProps)(ListItem);