React
useEffect
useEffect
hook lets you perform side effects in functional components.
useEffect
has 2 arguments:
- effectFunction: a function to be called when one of the
arrayDependencies
changes its value (The side effects you want to perform). This function can also return another function, which is called a Cleanup Function, React will call Cleanup Function every time right before this side effect is performed again and when the component unmounts. - arrayDependencies (Optional): an array of dependencies you want to keep track of changes and perform side effects when their values change. If
arrayDependencies
is not present, the side effect will be performed every time the component re-render.
// Calling signature
useEffect(effectFunction, arrayDependencies)
Basic Side Effect
If there are no dependencies, the side effect will be always performed whenever the component re-render.
function Count() {const [count, setCount] = useState(1)const handleClick = () => setCount(count + 1)useEffect(() => {document.title = `Current count is ${count}`})return (<div><div>Current count is {count}</div><Button onClick={handleClick}>+</Button><div>Look at the title of the current tab to see the side effect</div></div>)}
Effect with cleanup
Most side effects don't require any cleanup. However, some effects do. For example, we might want to set up a subscription to some external data source or add an event listeners to global elements. In that case, it is important to clean up so that we don't introduce a memory leak!
function Count() {const [count, setCount] = useState(1)useEffect(() => {const handleClick = () => setCount(count + 1)window.addEventListener("click", handleClick)return () => {window.removeEventListener("click", handleClick)}})return (<div><div>Current count is {count}</div><div>Click any where in the current window to increase count</div></div>)}
Multiple Effects
Multiple effects can be used within a component and make sure they are used to separate concerns. Don't combine multiple effects inside one big effect, since the dependencies of each effect can be different.
function Count() {const [count, setCount] = useState(1)useEffect(() => {document.title = `Current count is ${count}`})useEffect(() => {const handleClick = () => setCount(count + 1)window.addEventListener("click", handleClick)return () => {window.removeEventListener("click", handleClick)}}, [])return (<div><div>Current count is {count}</div><div>Click any where in the current window to increase count</div></div>)}
Effects with Dependencies
If the arrayDependencies
is empty, the effect will be performed only one time when the component is mounted. Otherwise, every time the component is re-rendered, React will keep checking for changes in arrayDependencies
to decide whether it should perform the side effect or not.
function Count() {const [count1, setCount1] = useState(1)const [count2, setCount2] = useState(1)const handleClick1 = () => setCount1(count1 + 1)const handleClick2 = () => setCount2(count2 + 1)useEffect(() => {document.title = `Current count is ${count1} - ${count2}`}, [count1])return (<div><div>Current count1 is {count1}</div><Button onClick={handleClick1}>+</Button><div>Look at the title of the current tab to see the side effect</div><div>Current count2 is {count2}</div><Button onClick={handleClick2}>+</Button><div>The title will not change when clicking above button</div></div>)}