Skip to content

Passing store data to a collected component can have unexpected results #102

@davidgilbertson

Description

@davidgilbertson

Consider this scenario with two components:

  • <TaskList> iterates over a list of tasks and for each, renders a <Task> component .
  • <Task> is wrapped in collect, but gets its data (a single task) passed to it as a prop.

The <Task> component is now controlled by Recollect. If, for example, a user ticks that task to mark it as 'complete', Recollect will target that individual <Task> component for an update. But when it re-renders, it will re-read its props, provided by <TaskList>, which hasn't re-rendered. So it will have the old data.

The solution in the above example is: don't wrap the lower level component in collect. Instead, it can be wrapped in React.memo() or a PureComponent.

This behaviour is unfortunate but necessary. Components need to always reference the original store they rendered with so that shouldComponentUpdate, componentDidUpdate etc have access to both 'previous' and 'next' store.

If you really need to pass data from the store into a collected component, and you understand what you're doing, you can shallow clone the object you're passing in which detach it from the store and bypass this warning.

In the future, Recollect might:

  • Only warn if the passed in data is modified (?)
  • Not warn at all, and subscribe both components to changes in the passed in props.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions