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

Allow hooks in class component render methods. #16116

Closed
FrobtheBuilder opened this issue Jul 12, 2019 · 3 comments
Closed

Allow hooks in class component render methods. #16116

FrobtheBuilder opened this issue Jul 12, 2019 · 3 comments

Comments

@FrobtheBuilder
Copy link

Do you want to request a feature or report a bug?
Feature.

What is the current behavior?
Currently, it is only possible to use hooks in function components. I know the rationale behind this is to encourage use of the function component pattern, and allow for future optimization work in the form of precompilation. However, it makes it very inconvenient to use modern hooks-based libraries in class components, and you're essentially forced to resort to using a higher order component instead, if one is even provided.
For instance, included with the react-i18next library is a very convenient useTranslation hook, yet, if you're localizing class components, you must wrap everything with a HOC, since the library no longer includes a decorator. The HOC pattern is especially nasty with Typescript since you essentially have to add a bunch of extra properties to your component's props interface and then have the HOC function strip them with a compound type.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:
N/A

What is the expected behavior?
Currently, it is actually possible to shim the core React hooks API to allow calling use... functions in class component render methods with react-universal-hooks. It even works with custom hooks provided by third party libraries, since the built-in hooks they call are wrapped. We're currently using this with the useTranslation hook from react-i18next with no issues.
I can't see any reason why this shouldn't be available natively, if only for compatibility and migration purposes. Render methods are just functions, and hooks are simply a way to allow repeated function calls to access persistent state from a backing list, correct? The hooks API documentation states that you shouldn't bother to refactor all your class components just for hooks, and even if that sort of usage wouldn't be possible to optimize through precompilation, allowing it would significantly ease the transition.
The only potential caveat is the common class component pattern of delegating out to subordinate render methods, in which hooks wouldn't work properly if they're called conditionally or in a loop. This can be avoided by passing hooked values from the top level render method instead.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Every version since hooks were added, 16.8.0 and up, all browsers obviously.

@gaearon
Copy link
Collaborator

gaearon commented Aug 15, 2019

It is an intentional decision to not support them classes because the mental models are subtly different and mixing them becomes very confusing. Such as how mutable this and captured props/state/callbacks interact.

This should help you though: https://reacttraining.com/blog/using-hooks-in-classes/

@gaearon gaearon closed this as completed Aug 15, 2019
@FrobtheBuilder
Copy link
Author

That link is the opposite of helpful because it shows you how to do the thing that I specifically don't want to need to do, just a different variant of it. I also don't really think it's that confusing as long as you remember the hook rules, but thanks anyway. At least we can keep using react-universal-hooks.

@Venryx
Copy link

Venryx commented Oct 27, 2019

It is an intentional decision to not support them classes because the mental models are subtly different and mixing them becomes very confusing. Such as how mutable this and captured props/state/callbacks interact.

That's a theoretical concern, but I've been using dozens of hooks in classes using react-universal-hooks, and I have yet to hit a single issue with it. (other than that the hook data isn't shown in react-devtools, which I've already made a workaround for)

Hooks in classes are useful to have because they give the ability to "gradually update" your components from classes to functions (or even leave some using both, where a class is more appropriate). I know the workaround you link to is an option, but it pollutes the react hierarchy and reduces the simplicity of the code through things like render props.

If there are technical reasons for not integrating the approach react-universal-hooks uses, then fair enough. But on it being confusing to use hooks in class-based render functions: I'm doing that right now, and am not seeing the concerns you mentioned come to light.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants