React Hooks Basics
Everything you need to get started with Hooks
React before hooks
I assume that you already have a grasp of React’s fundamentals, this is just a quick overview.
ReactJS is one of the most popular JavaScript front-end libraries which is efficient and flexible for building reusable UI components. React components lets you split your UI into reusable pieces and design them in isolation. Generally react components can be categorized into two types:
- Class components
- Functional components
Class Component
Class components can maintain their own state, re-render the components and all their children whenever the state changes and support all the react lifecycle methods. Class components make use of ES6 class and extend the Component class in React. These are also called the smart components.
import React, { Component } from “react”;
class MyComponent extends Component {
constructor(props){
super(props);
this.state = {
greeting: “Hello”;
}
}
render() {
return (
<div>
<p>{this.state.greeting} {this.props.name}</p>
</div>
);
}
}
export default MyComponent;
Functional Components
Functional Components are basic javascript functions or typically arrow functions. They are mainly used for presentation only. They don’t maintain state or support lifecycle methods and are generally called as the dumb components.
import React from “react”;
const MyComponent = props => (
<div>
<h1>Hello, {props.name}</h1>
</div>
);
export default MyComponent;
Few Drawbacks in the system:
Reusing Logic:
Whenever the code or the logic needs to be reused, we introduce the concepts of Higher Order Components (HOC) or RenderProps. But the downside side is that, the application needs to be restructured whenever we use them or else the application is likely to end up in the Wrapper hell.
Giant Components:
You must have come across a situation when you started a small and simple component but later turned out be quite the opposite and got hard to maintain and split up just because the stateful logic was all over the place.
Class Components:
Though I have been working with react for a while now, Classes have been always confusing. Either I forget to bind the event handlers or always find it difficult to distinguish when to use class or functional components. Sometimes you need to convert functional components to class components just to keep track of one state or in most cases we end up creating class components to be on the safer side.
The above three problems are all related. For instance, when trying to solve the wrapper hell by introducing more logic into the component, it results in the component turning out to be huge. On the other hand, if you split up the code and try using them as smaller components it will lead to nesting and wrapper hell. The classes are confusing in both the cases. The above three are not the actual problems but its symptoms.
React doesn’t provide a stateful primitive than a class component.
This is where Hooks comes to the rescue. Hooks are newest addition in React 16.8. Hooks are functions that let you access and manage react state and life cycle features from functional components. Hooks doesn’t work inside classes, they let you use react without classes.
- Hooks allow you to reuse stateful logic without changing your component hierarchy.
- Hooks let you split one component into smaller functions based on what pieces are related (such as setting up a subscription or fetching data), rather than forcing a split based on lifecycle methods.
- Hooks let you use more of React’s features without classes.
Uses of Hooks:
- Hooks allows to write organized code, increases readability, encourage better coding practices, boosts the performance of functional components.
- One major advantage of using hooks is that when class based and functional based components are converted to backward compatible JS code, the size of the converted class component is significantly more than a functional component. This is the reason the webpack chunk size increases, which can affect performance. Hooks solves this problem and reduce the size of the chunk.
useState
useState lets you use local state within functional component.
Declare state variable:
import React, { useState } from ‘react’
const displayAge = () => {
const [age, setAge] = useState(0);
return <div> Age = {age} </div>
}
//output -
Age = 0
In this example, the variable age is the state variable and setAge is the method to be called to update the state. useState takes in the initial state for the variable and returns an array of state and the function that allows us to change the state.
Update state variable:
import React, { useState } from ‘react’
const displayAge = () => {
const [age, setAge] = useState(0);
const handleClick = () => setAge(age + 1)
return (
<div>
My age is {age}
<div>
<button onClick?={handleClick}>Get older! </button>
</div>
</div>
)
}
Multiple state variables:
Multiple state variables can be used and updated from functional component. State variables can hold objects and arrays just fine, so you can still group related data together. However, unlike this.setState in a class, updating a state variable always replaces it instead of merging it.
import React, { useState } from ‘react’
const displayAge = () => {
const [age, setAge] = useState(20);
const [siblingsCount, setSiblingsCount] = useState(1);
const handleClick = () => setAge(age + 1)
const handleSiblingsNum = () => setSiblingsNum(siblingsNum + 1)
return (
<div>
<p> My age is {age}</p>
<p>I have {siblingsNum} siblings</p>
<div>
<button onClick?={handleClick}>Get older! </button>
<button onClick?={handleSiblingsNum}>
More siblings!
</button>
</div>
</div>
)
}
Object state variable :
useState also takes in objects. You could also set an object as initial state for useState.
() => {
const [state, setState] = useState({ age: 19, siblingsNum: 4 })
const handleClick = val =>
setState({
…state,
[val]: state[val] + 1
})
const { age, siblingsNum } = state
return (
<div>
<p>Today I am {age} Years of Age</p>
<p>I have {siblingsNum} siblings</p>
<div>
<button onClick?={handleClick.bind(null, ‘age’)}>Get older!</button>
<button onClick?={handleClick.bind(null, ‘siblingsNum’)}>
More siblings!
</button>
</div>
</div>
)
}
Functional setState:
The useState’s update function can also take in function similar to that of setState.
() => {
const [count, setCount] = useState(0);
return (
<>
<p>Count value is: {count}</p>
<button onClick?={() => setCount(0)}>Reset</button>
<button
onClick={() => setCount(prevCount => prevCount + 1)}>
Plus (+)
</button>
<button
onClick={() => setCount(prevCount => prevCount — 1)}>
Minus (-)
</button>
</>
);
}
useEffect
The Effect Hook lets you perform side effects and allows you to use lifecycle methods in function components. To be precise, it can perform actions of componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods.
The syntax of useEffect ,
useEffect (( )=> {
console.log(“Inside useEffect”)
}, [ ] )
useEffect receives two parameters,
- function
- array( optional )
In short, useEffect is invoking that function based on the second parameter. Whenever the value of the state changes, the component will be re-rendered and the execution of useEffect is determined by the values in the array. If any of the variables state which is inside the array changes, the useEffect will be called in the re-render. The value of variable’s state will be compared to its previous state, if the values are different then useEffect will be executed.
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`I have been clicked ${count} times`);
}, [count]);
return (
<div>
<button onClick?={() => setCount(count + 1)}>Click me!</button>
</div>
);
In the above case the output will be,
// I have been clicked 0 times
// I have been clicked 1 times
// I have been clicked 2 times
Every time the value of count changes, the component will be re-rendered and useEffect will be called. This is similar to the functioning of ComponentDidUpdate.
When the array is empty,
useEffect(() => {
console.log(`I have been clicked ${count} times`);
}, []);
// I have been clicked 0 times
If we leave the array empty, after the first render useEffect will be called and during subsequent re-renders there is no value in the array to compare and hence there is no change. Therefore it won’t be executed in the re-render. This is similar to the functioning of componentDidMount.
When the second parameter is not given,
useEffect(() => {
console.log(`I have been clicked ${count} times`);
});
// I have been clicked 0 times
// I have been clicked 1 times
// I have been clicked 2 times
In this case, the function will be invoked in every re-rendered. No value is passed and therefore no comparison is made.
This article originally appeared on the Medium. Click the link below to view.
Fullstack Developer
3 天前Hi,I have an experience of a year in Reactjs. Now I'm into fullstack development and looking for a job
Engineering Leader | Ex-Entrepreneur | IIT Madras CSE
5 年Good work