Repository: react
Issue: Umbrella: Chopping Block
Labels: Type: Umbrella,React Core Team

I wanted to create a list of things whose existence makes React bigger and more complicated than necessary. This makes them more likely to need to be deprecated and actually removed in a future version. No clue of when this will happen and what the recommended upgrade path will be so don't take this issue as advice that you should move away from them until there's clear upgrade advice. You might make it worse by doing so.

(This has some overlap with https://github.com/facebook/react/issues/9475 but those seem more longer term.)

- [ ] __Unsafe Life Cycles without UNSAFE prefix__ - We'll keep the ones prefixed UNSAFE indefinitely but the original ones will likely be deprecated and removed.

- [ ] __Legacy context__ - `.contextTypes`, `.childContextTypes`, `getChildContext` - The old context is full of edge cases for when it is accidentally supposed to work and the way it is designed requires all React code to become slower just to support this feature.

- [ ] __String refs__ - This requires current owner to be exposed at runtime. While it is likely that some form of owner will remain, this particular semantics is likely not what we want out of it. So rather than having two owners, we should just remove this feature. It also requires an extra field on every ReactElement which is otherwise not needed.

- [ ] __Module pattern components__ - This is a little used feature that lets you return a class instance from a regular function without extending `React.Component`. This is not that useful. In practice the ecosystem has moved around ES class like usage, and other language compiling to JS tries to comply with that model as well. The existence of this feature means that we don't know that something is a functional component by just testing if it's a function that is not extending `React.Component`. Instead we have to do some extra feature testing for every functional component there is. It also prevents us from passing the ref as the second argument by default for all functional components without using `forwardRef` since that wouldn't be valid for class components.

- [ ] __Uncontrolled onInput__ - This is described in #9657. Because we support uncontrolled polyfilling of this event, we have to do pretty invasive operations to the DOM like attaching setters. This is all in support of imperative usage of the DOM which should be out-of-scope for React.

- [ ] __setState in componentDidCatch__ - Currently we support error recovery in `componentDidCatch` but once we support `getDerivedStateFromCatch` we might want to consider deprecating the old mechanism which automatically first commits null. The semantics of this are a bit weird and requires complicated code that we likely get wrong sometimes.

- [ ] __Context Object As Consumer__ - Right now it is possible to use the Context object as a Consumer render prop. That's an artifact of reusing the same object allocation but not documented. We'll want to deprecate that and make it the Provider instead.

- [ ] __No GC of not unmounted roots__ - This likely won't come with a warning. We'll just do it. It's not a breaking behavior other than memory usage. You have to call `unmountComponentAtNode` or that component won't be cleaned up. Almost always it is not cleaned up anyway since if you have at least one subscription that still holds onto it. Arguably this is not even a breaking change. #13293

- [ ] __unstable_renderSubtreeIntoContainer__ - This is replaced by Portals. It is already problematic since it can't be used in life-cycles but it also add lots of special case code to transfer the context. Since legacy context itself likely will be deprecated, this serves no purposes.

- [x] __ReactDOM.render with hydration__ - This has already been deprecated. This requires extra code and requires us to generate an extra attribute in the HTML to auto-select hydration. People should be using ReactDOM.hydrate instead. We just need to remove the old behavior and the attribute in ReactDOMServer.

- [ ] __Return value of `ReactDOM.render()`__ - We can't synchronously return an instance when inside a lifecycle/callback/effect, or in concurrent mode. Should use a ref instead.

- [ ] __All of `ReactDOM.render()`__ - Switch everyone over to `createRoot`, with an option to make `createRoot` sync.