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.