Skip to content

Data: withSelect: Subscription callbacks linger after renderToString #13879

Closed
@aduth

Description

@aduth

Previously: #11777 (comment)
Attempted (closed) resolution: #11819

The implementation of withSelect attaches a store subscriber in its constructor, assuming that the subscription would be removed in a subscription componentWillUnmount. However, in the context of renderToString, a constructor is called but componentWillUnmount will never be called. Thus, data-bound components will leave lingering subscription callbacks after being rendered via renderToString.

From @jsnajdr at #11777 (comment)

Subscribing in constructor can cause subscriptions to leak in two cases:

  • when server-side rendering, constructor is called, but componentWillUnmount never is.
  • in React Fiber concurrent mode, component instances can be constructed, but never actually committed to DOM. This can happen when Fiber is working through rendering a low-priority update (calling constructors and render methods) and suddenly a higher priority update is scheduled that invalidates the work that's been done. Then the unfinished low-priority work will be thrown away and restarted. In such a case, constructor is called, but the component(DidMount|WillUnmount) methods aren't.

The correct place to subscribe is therefore always componentDidMount.

Then, of course, we might miss a store update that happened between constructor and componentDidMount.

react-redux solves that by rerunning the selector (i.e., mapStateToProps) in componentDidMount and calling forceUpdate if anything changed. That's the stable v5.1.1.

In master, they have an unreleased beta version where the Redux provider and consumer are rewritten using the new React context API and where the connect-ed consumers don't subscribe to the store at all. Just the Provider does. That could be an inspiration for the @wordpress/data internals, too 🙂

Conclusion: this patch solves the bug that @Tug discovered, but other subtle issues are still present.

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Package] Data/packages/data[Type] BugAn existing feature does not function as intended

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions