React - useEffect hook
In this article, we would like to show you how to use React useEffect
hook.
React useEffect
hook is equivalent to the class components lifecycle methods:
componentDidMount
,componentDidUpdate
,componentWillUnmount
.
The function inside useEffect
runs when the component is first rendered and on every array of dependencies update (which is the second, optional argument).
Below examples present:
- how to import
useEffect
hook, - solution with one argument only (arrow function),
- solution with two arguments:
- array of dependencies that is monitored for changes,
- empty array of dependencies.
- how to mix
useEffect
1. Import
The first thing you need to do is import useEffect
hook the following way:
import React, { useEffect } from 'react';
2. One argument example (only arrow function)
The arrow function inside useEffect
is always executed after:
- the rendering cycle,
- props, state or context change,
- the parent component is rendered.
Runnable example:
// ONLINE-RUNNER:browser;
// Note: Uncomment import lines while working with JSX Compiler.
// import React, { useEffect } from 'react';
// import ReactDOM from 'react-dom';
const App = () => {
const [counter, setCounter] = React.useState(0);
React.useEffect(() => {
console.log(`useEffect: counter: ${counter}`);
});
return (
<div>
<p>
<b>Counter: </b>{counter}
</p>
<button onClick={() => setCounter(counter + 1)}>Change counter</button>
</div>
);
};
const root = document.querySelector('#root');
ReactDOM.render(<App />, root );
3. Two arguments example (arrow function + dependency list)
The function inside useEffect
is executed in two cases:
- after the component is mounted,
- after any change of the monitored array of dependencies (in our case on the
user
change).
Note:
In one
useEffect
array of dependencies we can put many variables.
Runnable example:
// ONLINE-RUNNER:browser;
// Note: Uncomment import lines while working with JSX Compiler.
// import React, { useEffect } from 'react';
// import ReactDOM from 'react-dom';
const App = () => {
const [user, setUser] = React.useState('Tom');
const [counter, setCounter] = React.useState(0);
React.useEffect(() => {
console.log(`useEffect: Hello ${user}!`);
}, [user]);
return (
<div>
<p>
<b>User: </b> {user},<b>Counter: </b> {counter}
</p>
<button onClick={() => setCounter(counter + 1)}>Change counter</button>
<button onClick={() => setUser(user === 'Tom' ? 'Kate' : 'Tom')}>
Change user
</button>
</div>
);
};
const root = document.querySelector('#root');
ReactDOM.render(<App />, root );
4. Empty array of dependencies example
In this example, we create useEffect
hook with an empty array of dependencies. That tells React to execute the effect only once (at component mount).
Runnable example:
// ONLINE-RUNNER:browser;
// Note: Uncomment import lines while working with JSX Compiler.
// import React, { useEffect } from 'react';
// import ReactDOM from 'react-dom';
const App = () => {
const [counter, setCounter] = React.useState(0);
React.useEffect(() => {
console.log('Setting counter...');
}, []);
return (
<div>
<p>
<b>Counter: </b> {counter}
</p>
<button onClick={() => setCounter(counter + 1)}>Increment</button>
</div>
);
};
const root = document.querySelector('#root');
ReactDOM.render(<App />, root );
5. We can mix useEffect
We can also use many useEffect
hooks and mix them as we want.
Runnable example:
// ONLINE-RUNNER:browser;
// Note: Uncomment import lines while working with JSX Compiler.
// import React, { useEffect } from 'react';
// import ReactDOM from 'react-dom';
const App = () => {
const [counter1, setCounter1] = React.useState(0);
const [counter2, setCounter2] = React.useState(0);
React.useEffect(() => {
console.log('Setting counters...');
}, []);
React.useEffect(() => {
console.log(`Counter 1 value is now ${counter1}`);
}, [counter1]);
React.useEffect(() => {
console.log(`Counter 2 value is now ${counter2}`);
}, [counter2]);
return (
<div>
<p>
<b>Counter 1: </b> {counter1}, <b>Counter 2: </b> {counter2}
</p>
<button onClick={() => setCounter1(counter1 + 1)}>Increment 1</button>
<button onClick={() => setCounter2(counter2 + 1)}>Increment 2</button>
</div>
);
};
const root = document.querySelector('#root');
ReactDOM.render(<App />, root );