Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate marking a React node as a store "owner" #43

Closed
bcherny opened this issue Jun 11, 2018 · 1 comment
Closed

Investigate marking a React node as a store "owner" #43

bcherny opened this issue Jun 11, 2018 · 1 comment

Comments

@bcherny
Copy link
Owner

bcherny commented Jun 11, 2018

An issue with Flux and Redux is the inability to garbage collect stores. Today, Undux suffers from the same issue: because each store is a singleton defined at the top level in a module, there's no way to safely garbage collect it today.

This is an issue when using Undux in complex applications with many React roots (ie. ReactDOM.render is called for lots of mount points), like facebook.com. In applications like that, if a particular root makes use of a particular Undux store, it's desirable to GC the store when its corresponding React root unmounts.

One way to do that is to speciate withStore into two kinds of withStore:

  1. A withStore that indicates that the component that is wrapped is a React root. When that component unmounts, we should GC the store. Let's call it withStoreRoot.
  2. A withStore that indicates that the component this is wrapped is not a React root, and is just a regular store-consuming component. This is how withStore behaves today.

This approach would also mean forbidding declaring and using store at the top level. Instead, we'd expose a way to create a "store factory", and store could only be used in React components and Undux Plugins. This has the downside of making writing Undux Actions more painful, but could ultimately be a good way to enforce good architecture (similar to #36).

If we go with this approach, we need a way to enforce that all withStore calls for a given store are descendents in the React tree of their corresponding withStoreRoot call. Otherwise, we run into a weird case where a root unmounts, the store is GC'd, but there's still a child component holding onto a stale StoreSnapshot prop.

This kind of enforcement is really hard. We can do it at runtime (similar to how React.createContext works), but ideally we want to do it at compile time. Compile time enforcement with a type system doesn't seem to be possible: neither TypeScript nor Flow support recursively constraining JSX child types (microsoft/TypeScript#21699). So we're stuck with runtime enforcement for now.

Exploration here: https://gist.github.com/bcherny/f360f417e8768558684ec3e379f9e354

@bcherny
Copy link
Owner Author

bcherny commented Jul 26, 2018

3909ed9

@bcherny bcherny closed this as completed Jul 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant