How can I use React hooks in React classic `class` component?

JavascriptReactjsReact Hooks

Javascript Problem Overview


In this example, I have this react class:

class MyDiv extends React.component
   constructor(){
      this.state={sampleState:'hello world'}
   }
   render(){
      return <div>{this.state.sampleState}
   }
}

The question is if I can add React hooks to this. I understand that React-Hooks is alternative to React Class style. But if I wish to slowly migrate into React hooks, can I add useful hooks into Classes?

Javascript Solutions


Solution 1 - Javascript

High order components are how we have been doing this type of thing until hooks came along. You can write a simple high order component wrapper for your hook.

function withMyHook(Component) {
  return function WrappedComponent(props) {
    const myHookValue = useMyHook();
    return <Component {...props} myHookValue={myHookValue} />;
  }
}

While this isn't truly using a hook directly from a class component, this will at least allow you to use the logic of your hook from a class component, without refactoring.

class MyComponent extends React.Component {
  render(){
    const myHookValue = this.props.myHookValue;
    return <div>{myHookValue}</div>;
  }
}

export default withMyHook(MyComponent);

Solution 2 - Javascript

Class components don't support hooks -

According to the Hooks-FAQ:

> You can’t use Hooks inside of a class component, but you can definitely mix classes and function components with Hooks in a single tree. Whether a component is a class or a function that uses Hooks is an implementation detail of that component. In the longer term, we expect Hooks to be the primary way people write React components.

Solution 3 - Javascript

As other answers already explain, hooks API was designed to provide function components with functionality that currently is available only in class components. Hooks aren't supposed to used in class components.

Class components can be written to make easier a migration to function components.

With a single state:

class MyDiv extends Component {
   state = {sampleState: 'hello world'};

   render(){
      const { state } = this;
      const setState = state => this.setState(state);

      return <div onClick={() => setState({sampleState: 1})}>{state.sampleState}</div>;
   }
}

is converted to

const MyDiv = () => {
   const [state, setState] = useState({sampleState: 'hello world'});

   return <div onClick={() => setState({sampleState: 1})}>{state.sampleState}</div>;
}

Notice that useState state setter doesn't merge state properties automatically, this should be covered with setState(prevState => ({ ...prevState, foo: 1 }));

With multiple states:

class MyDiv extends Component {
   state = {sampleState: 'hello world'};

   render(){
      const { sampleState } = this.state;
      const setSampleState = sampleState => this.setState({ sampleState });

      return <div onClick={() => setSampleState(1)}>{sampleState}</div>;
   }
}

is converted to

const MyDiv = () => {
   const [sampleState, setSampleState] = useState('hello world');

   return <div onClick={() => setSampleState(1)}>{sampleState}</div>;
}

Solution 4 - Javascript

Complementing Joel Cox's good answer


Render Props also enable the usage of Hooks inside class components, if more flexibility is needed:

class MyDiv extends React.Component {
  render() {
    return (
      <HookWrapper
        // pass state/props from inside of MyDiv to Hook
        someProp={42} 
        // process Hook return value
        render={hookValue => <div>Hello World! {hookValue}</div>} 
      />
    );
  }
}

function HookWrapper({ someProp, render }) {
  const hookValue = useCustomHook(someProp);
  return render(hookValue);
}

For side effect Hooks without return value:

function HookWrapper({ someProp }) {
  useCustomHook(someProp);
  return null;
}

// ... usage
<HookWrapper someProp={42} />

Source: React Training

Solution 5 - Javascript

Hooks are not meant to be used for classes but rather functions. If you wish to use hooks, you can start by writing new code as functional components with hooks

According to React FAQs

> You can’t use Hooks inside of a class component, but you can > definitely mix classes and function components with Hooks in a single > tree. Whether a component is a class or a function that uses Hooks is > an implementation detail of that component. In the longer term, we > expect Hooks to be the primary way people write React components.

const MyDiv = () => {
   const [sampleState, setState] = useState('hello world');
   render(){
      return <div>{sampleState}</div>
   }
}

Solution 6 - Javascript

you can achieve this by generic High order components

HOC

import React from 'react';
const withHook = (Component, useHook, hookName = 'hookvalue') => {
  return function WrappedComponent(props) {
    const hookValue = useHook();
    return <Component {...props} {...{[hookName]: hookValue}} />;
  };
};

export default withHook;

Usage

class MyComponent extends React.Component {
      render(){
        const myUseHookValue = this.props.myUseHookValue;
        return <div>{myUseHookValue}</div>;
      }
    }

export default withHook(MyComponent, useHook, 'myUseHookValue');

Solution 7 - Javascript

You can use the react-universal-hooks library. It lets you use the "useXXX" functions within the render function of class-components.

It's worked great for me so far. The only issue is that since it doesn't use the official hooks, the values don't show react-devtools.

To get around this, I created an equivalent by wrapping the hooks, and having them store their data (using object-mutation to prevent re-renders) on component.state.hookValues. (you can access the component by auto-wrapping the component render functions, to run set currentCompBeingRendered = this)

For more info on this issue (and details on the workaround), see here: https://github.com/salvoravida/react-universal-hooks/issues/7

Solution 8 - Javascript

Stateful components or containers or class-based components ever support the functions of React Hooks, so we don't need to React Hooks in Stateful components just in stateless components.

Some additional informations

What are React Hooks? So what are hooks? Well hooks are a new way or offer us a new way of writing our components.

Thus far, of course we have functional and class-based components, right? Functional components receive props and you return some JSX code that should be rendered to the screen.

They are great for presentation, so for rendering the UI part, not so much about the business logic and they are typically focused on one or a few purposes per component.

Class-based components on the other hand also will receive props but they also have this internal state. Therefore class-based components are the components which actually hold the majority of our business logic, so with business logic, I mean things like we make an HTTP request and we need to handle the response and to change the internal state of the app or maybe even without HTTP. A user fills out the form and we want to show this somewhere on the screen, we need state for this, we need class-based components for this and therefore we also typically use class based components to orchestrate our other components and pass our state down as props to functional components for example.

Now one problem we have with this separation, with all the benefits it adds but one problem we have is that converting from one component form to the other is annoying. It's not really difficult but it is annoying.

If you ever found yourself in a situation where you needed to convert a functional component into a class-based one, it's a lot of typing and a lot of typing of always the same things, so it's annoying.

A bigger problem in quotation marks is that lifecycle hooks can be hard to use right.

Obviously, it's not hard to add componentDidMount and execute some code in there but knowing which lifecycle hook to use, when and how to use it correctly, that can be challenging especially in more complex applications and anyways, wouldn't it be nice if we had one way of creating components and that super component could then handle both state and side effects like HTTP requests and also render the user interface?

Well, this is exactly what hooks are all about. Hooks give us a new way of creating functional components and that is important.

Solution 9 - Javascript

React Hooks let you use react features and lifecycle without writing a class. It's like the equivalent version of the class component with much smaller and readable form factor. You should migrate to React hooks because it's fun to write it. But you can't write react hooks inside a class component, as it's introduced for functional component.

This can be easily converted to :

class MyDiv extends React.component
   constructor(){
      this.state={sampleState:'hello world'}
   }
   render(){
      return <div>{this.state.sampleState}
   }
}

const MyDiv = () => {
   const [sampleState, setSampleState] = useState('hello world');
   return <div>{sampleState}</div>
}

Solution 10 - Javascript

It won't be possible with your existing class components. You'll have to convert your class component into a functional component and then do something on the lines of -

function MyDiv() {
const [sampleState, setSampleState] = useState('hello world');
return (
      <div>{sampleState}</div>
    )
}

Solution 11 - Javascript

For me React.createRef() was helpful.

ex.:

constructor(props) {
      super(props);
      this.myRef = React.createRef();
   }

...


<FunctionComponent ref={this.myRef} />

Origin post here.

Solution 12 - Javascript

I've made a library for this. React Hookable Component.

Usage is very simple. Replace extends Component or extends PureComponent with extends HookableComponent or extends HookablePureComponent. You can then use hooks in the render() method.

import { HookableComponent } from 'react-hookable-component';

//                                  πŸ‘‡πŸ‘‡πŸ‘‡πŸ‘‡πŸ‘‡πŸ‘‡πŸ‘‡πŸ‘‡
class ComponentThatUsesHook extends HookableComponent<Props, State> {
	render() {
		//            πŸ‘‡πŸ‘‡πŸ‘‡πŸ‘‡πŸ‘‡πŸ‘‡
		const value = useSomeHook();
		return <span>The value is {value}</span>;
	}
}

Solution 13 - Javascript

Yes, but not directly.

Try react-iifc, more details in its readme.

https://github.com/EnixCoda/react-iifc

Solution 14 - Javascript

  1. Try with-component-hooks: https://github.com/bplok20010/with-component-hooks
import withComponentHooks from 'with-component-hooks';


class MyComponent extends React.Component {

    render(){
        const props = this.props;
        const [counter, set] = React.useState(0);

        //TODO...

    }
}

export default withComponentHooks(MyComponent)

2.Try react-iifc: https://github.com/EnixCoda/react-iifc

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAminadav GlickshteinView Question on Stackoverflow
Solution 1 - JavascriptJoel CoxView Answer on Stackoverflow
Solution 2 - JavascriptGilad BarView Answer on Stackoverflow
Solution 3 - JavascriptEstus FlaskView Answer on Stackoverflow
Solution 4 - Javascriptford04View Answer on Stackoverflow
Solution 5 - JavascriptShubham KhatriView Answer on Stackoverflow
Solution 6 - JavascriptMuhammad NumanView Answer on Stackoverflow
Solution 7 - JavascriptVenryxView Answer on Stackoverflow
Solution 8 - JavascriptAllan DuarteView Answer on Stackoverflow
Solution 9 - Javascriptkk_360View Answer on Stackoverflow
Solution 10 - JavascriptAseem UpadhyayView Answer on Stackoverflow
Solution 11 - JavascriptFikretView Answer on Stackoverflow
Solution 12 - JavascriptwishaView Answer on Stackoverflow
Solution 13 - JavascriptEnixCodaView Answer on Stackoverflow
Solution 14 - JavascriptNoBoView Answer on Stackoverflow