How to use hooks in React Class Components ?

I got a contract with this web3 company, Pixul, as a Frontend Developer a few months ago, and the first project I was assigned to used class components. This was my first ever job as web developer, I was afraid and confused because I had never before worked with class components in React. After reading several articles and ReactJS documentation, I began to understand class components and react lifecycle methods.

I'm not going to teach you in-depth about class components or Javascript classes in this article. Rather I'd quickly go over how can you replicate the behaviour and function of some commonly used React Hooks like useState, useEffect,useRef in Class Components with Lifecycle methods.

useState

Using useState in class components is very simple just, declare the state variables inside the constructor and update them using this.setState() method. Go through the code below to understand.

In React Functional Components:

const Hashnode = () => {
  const [inputFieldState, setInputFieldState] = useState('')
  return (
      <input
        type="text"
        value={inputFieldState}
        onChange={(e) => {setInputFieldState(e.target.value)}}
      />
       );    
}

In React Class Components:

class HashNode extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      inputFieldState: ''
    }
 }
 render() {
    return (
        <input
          type="text"
          value={inputFieldState}
          onChange={(e) => {this.setState({inputFieldState: e.target.value})}}
        />
    );
   }
 }
}

useEffect

The useEffect hook single handedly replaces three lifecycle methods componentDidMount, componentWillUnmount, componentDidUpdate. Let's have a look how it does so.

In React Functional Components:

const Hashnode = () => {
  useEffect(() => {
   //componentDidMount
   //Attach any event listeners
   //Make any network calls or any DOM manipulation
return () => { 
   //componentWillUnmount
   //Cleanup function
 };  
},[])

 return //anything       
}

By leaving the dependency array empty in the above code, we ensure that the callback function of useEffect runs only once when the component mounts and the function that the callback function returns runs only once when the component unmounts.

Let's see how to replicate it in React Class Components:

class HashNode extends React.Component {
  constructor(props) {
    super()
   //declare state 
  }  
componentDidMount() {
   //Attach any event listeners
  //Make any network calls or any DOM manipulation
}
componentWillUnmount() {
  //Cleanup function
}
render() {
    return //anthing
 }
}

Replicating this basic usage of useEffect was very simple and easy. Another major usage of useEffect is to run a piece of code when a state or props changes.

In React Functional Components:

const Hashnode = () => {
  useEffect(() => {
   //Run some code when any value in dependency array changes
},[state1, state2, prop1, prop2])

return //anything       
}

Let's see how to replicate it in React Class Components:

class HashNode extends React.Component {
  constructor(props) {
    super()
      //declare state
  }   
  componentDidUpdate(prevProps,prevState) {
    if (this.props.someThing !== prevProps.someThing) {
      //run some code
    }
    //Also
    if (this.state.someThing !== prevState.someThing) {
      //run some code
    }
  }
render() {
    return //anthing
 }
}

So in case of class components we have to compare the current and previous value of state or props and then run the required piece of code. The lifecycle method componentDidUpdate runs after every render. If you have a useEffect that runs some code after every render (a useEffect with no dependency array) you can also replicate that with componentDidUpdate lifecycle method.

useRef

Using refs in class components is simple you just need to declare the ref inside the constructor with React.createRef() and assign it to a DOM element.

Let's see how we do it:

class HashNode extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }
  const displayValue = () => {
    console.log(this.inputRef.current.value)
  };
  render() {
    return <input type="number" ref={this.inputRef} />;
  }
}

P.S. - Ref in react is not just a to access a reference to an underlying DOM Element. It can hold any mutable value in it's .current property. For more refer to the ReactJS official documentation.

Class components are now considered legacy code; if you are creating a new project, no one will advise you to use class components. Class components should be used only for very specific needs that cannot be handled by a functional component, and only for learning purposes. Even in my company, on my recommendation, my coworker and I converted the enter codebase from class to functional component.

Thank you for reading!!! Have a wonderful day.