Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class. We can use the features of class component in the functional component by using the react hooks. useState and useEffect are features of the functional components used for State Management and managing the side effects in the components respectively.
useState
The state of a functional component can be managed using the useState hook. For this we can use the useState()
function provided by react.
const [state, setState] = useState(initialValue)
Here, state is a variable that will store the value and setState is a function that will modify the value. An initial value is passed to useState. The initial value can be of any type.
Lets take an example:
import React, {useState} from 'react'
function Example() {
const [value, setValue] = useState(0)
const handleDecrement = () => {
setValue(value - 1);
}
const handleIncrement = () => {
setValue(value + 1)
}
return (
<div>
<button onClick={handleDecrement}>-</button>
<span>{value}</span>
<button onClick={handleIncrement}>+</button>
</div>
)
}
export default Example
This is a simple example of increment and decrement in a value. We have set the initial state of the value to 0. So, on increment we call the setValue function and increase the current value by 1 and on decrement we call setValue function and decrease the current value by 1.
useEffect
useEffect handles the side-effects of the functional component. By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative API. It removes the need for componentDidMount
,componentDidUpdateand
and componentWillUnmount
.
useEffect()
hook accepts 2 arguments: callback and dependencies.
useEffect(callback, [dependencies]);
The side-effects are written inside callback function.
The dependencies argument lets you control when the side-effect runs. There can be three conditions of providing the dependencies:
- Not provided: the side-effect runs after every rendering.
import React , {useState , useEffect} from 'react'
function Example() {
const [count , setCount ] = useState(0);
useEffect(()=>{
console.log('click')
}) // no dependencies provided
return (
<div>
<button onClick={()=>setCount(count+1)}>click me !</button>
<span>you clicked {count} times</span>
</div>
)
}
export default Example
Output:
Here, we can see that the function inside useEffect ie. console.log("click")
runs every time we click on the button.
2. An empty array[]
: the side-effect runs once after the initial rendering.
import React , {useState , useEffect} from 'react'
function Example() {
const [count , setCount ] = useState(0);
useEffect(()=>{
console.log('click')
} ,[]) // empty dependencies provided
return (
<div>
<button onClick={()=>setCount(count+1)}>click me !</button>
<span>you clicked {count} times</span>
</div>
)
}
export default Example
Output:
Here, we can see that the function inside useEffect runs only once no matter how many times we click on the button.
3. Has props or state values [prop1, prop2, state1, state2]
: the side-effect runs once after initial rendering and after every rendering ONLY IF `prop` or `state` changes.
import React , {useState , useEffect} from 'react'
function Example() {
const [count , setCount ] = useState(0);
useEffect(()=>{
console.log('click')
}, [count]) // state value provided
return (
<div>
<button onClick={()=>setCount(count+1)}>click me !</button>
<span>you clicked {count} times</span>
</div>
)
}
export default Example
Output:
Here, we can see that the function inside useEffect runs once after initial rendering and after every time we press on the button.
useEffect is mostly used to perform data fetching side-effects.
The following component fetchUsers()
fetches the users list over the network:
function FetchUsers() {
const [users, setUsers] = useState([]);
useEffect( () => {
async function fetchData() {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const userData = await response.data;
setUsers(userData );
}
fetchData();
}, []);
return (
<div>
{users.map(item=> <li>{item.name}</li>)}
</div>
);
}
Here, useEffect()
starts a fetch request by calling fetchData()
async function after the initial mounting. When the request completes, setUsers(userData )
updates the users
state with the just fetched users list.
Conclusion
useState()
is a hook that manages state in a functional components. It takes the initial state as an argument and returns an array of two entries , state and setState . state is a variable that stores the value of the state and setState is a function that modifies the value of the state and useEffect()
is a hook that manages the side effects in the functional components. useEffect hooks consists of a callback function and dependencies. In case of no dependencies provided, the call back function runs on every render. If empty array of dependencies provided, the callback function runs only once and if props or state values are provided then the callback function runs once in initial render and after every change in the provided props or state.