I have a list of items that is rendered by the list like so:
items.map(item => (
<ListItem
item={item}
updates={updates[item.id]}
{/** other props like deleting loading*/}
/>
));
Note that item here is not what is passed to the action creator functions, ListItem is a container that will change this.
My item container has an optimized mapStateToProps (it returns a function, not an object):
const mapDispatchToProps = {
updateItem,
//others
}
const mapStateToProps = () => {
//create momoized state creator
const memoizedStateCreator = createMemoized();
return (unused, { item, updates }) =>
//use memoized state creator
memoizedStateCreator(item, updates);
};
In the item when I click to save the item I have something like this:
<button onclick={updateItem(item)}
I would like to change this to
<button onclick={updateItem}
For that I can use mergeProps but that would cause render of the Item (the Item function) to be called even though nothing changed because I always return a new reference as props. It would also cause react to do a shadow DOM compare of the result (instead of pure component that would skip that)
MergeProps cannot be optimized with a factory function (like mapStateToProps) where I can create a memoized function.
const mergeProps = (stateProps, dispatchProps) => ({
...stateProps,
...dispatchProps,
updateItem: () =>
stateProps.updateItem(stateProps.item),
});
One way to do this is to not use mergeProps at all and use a wrapper function instead:
const wrapper = props =>
ListItem({
...props,
updateItem: () => props.updateItem(props.item),
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(memo(wrapper));
My question is; is there a way to do this with mergeProps without having to turn my functional components into classes?
Returning a function from mapDispatchToProps would not work in my case because item does not come from ownProps, it comes from mapStateToProps