10/11/2024, 01:26 Projects | 100xDevs
Custom Hooks 3 of 5
1 - What are hooks
What are hooks
Hooks are a feature introduced in React 16.8 that allow you to use
state and other React features without writing a class. They are
functions that let you "hook into" React state and lifecycle
features from function components.
State
Functional
import React, { useState } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount(count + 1);
};
return (
<div>
[Link] 1/19
10/11/2024, 01:26 Projects | 100xDevs
<p>{count}</p>
<button onClick={incrementCount}>Increment</button>
Custom Hooks 3 of 5
</div>
);
}
Class Based
class MyComponent extends [Link] {
constructor(props) {
super(props);
[Link] = { count: 0 };
}
incrementCount = () => {
[Link]({ count: [Link] + 1 });
}
render() {
return (
<div>
<p>{[Link]}</p>
<button onClick={[Link]}>Increment</button
</div>
);
}
}
Lifecycle events
Functional
[Link] 2/19
10/11/2024, 01:26 Projects | 100xDevs
import React, { useState, useEffect } from 'react';
Custom Hooks 3 of 5
function MyComponent() {
useEffect(() => {
// Perform setup or data fetching here
return () => {
// Cleanup code (similar to componentWillUnmount)
};
}, []);
// Render UI
}
Class based
class MyComponent extends [Link] {
componentDidMount() {
// Perform setup or data fetching here
}
componentWillUnmount() {
// Clean up (e.g., remove event listeners or cancel subscriptio
}
render() {
// Render UI
}
}
Functional solution
import React, { useEffect, useState } from 'react'
import './[Link]'
function App() {
const [render, setRender] = useState(true);
useEffect(() => {
setInterval(() => {
setRender(r => !r);
}, 5000)
[Link] 3/19
10/11/2024, 01:26 Projects | 100xDevs
}, []);
Custom Hooks 3 of 5
return (
<>
{render ? <MyComponent /> : <div></div>}
</>
)
}
function MyComponent() {
useEffect(() => {
[Link]("component mounted");
return () => {
[Link]("component unmounted");
};
}, []);
return <div>
From inside my component
</div>
}
export default App
Until now we’re seen some commonly used hooks in React-
1. useState
2. useEffect
3. useMemo
4. useCallback
These hooks are provided to you by the React library.
[Link] 4/19
10/11/2024, 01:26 Projects | 100xDevs
2 - What are custom
Custom Hooks 3 of 5
hooks
Hooks that you create yourself, so other people can use them
are called custom hooks.
A custom hook is effectively a function, but with the following
properties -
1. Uses another hook internally (useState, useEffect, another
custom hook)
2. Starts with use
A few good examples of this can be
1. Data fetching hooks
2. Browser functionality related hooks - useOnlineStatus ,
useWindowSize, useMousePosition
3. Performance/Timer based - useInterval, useDebounce
[Link] 5/19
10/11/2024, 01:26 Projects | 100xDevs
Custom Hooks 3 of 5
3 - Data fetching hooks
Data fetching hooks can be used to encapsulate all the logic to
fetch the data from your backend
For example, look at the following code-
import { useEffect, useState } from 'react'
import axios from 'axios'
function App() {
const [todos, setTodos] = useState([])
useEffect(() => {
[Link]("[Link]
.then(res => {
setTodos([Link]);
})
}, [])
return (
<>
{[Link](todo => <Track todo={todo} />)}
</>
)
}
function Track({ todo }) {
return <div>
{[Link]}
<br />
{[Link]}
</div>
}
export default App
[Link] 6/19
10/11/2024, 01:26 Projects | 100xDevs
Custom Hooks 3 of 5
Step 1 - Converting the data fetching bit to
a custom hook
import { useEffect, useState } from 'react'
import axios from 'axios'
function useTodos() {
const [todos, setTodos] = useState([])
useEffect(() => {
[Link]("[Link]
.then(res => {
setTodos([Link]);
})
}, [])
return todos;
}
function App() {
const todos = useTodos();
return (
<>
[Link] 7/19
10/11/2024, 01:26 Projects | 100xDevs
{[Link](todo => <Track todo={todo} />)}
</>
Custom Hooks 3 of 5
)
}
function Track({ todo }) {
return <div>
{[Link]}
<br />
{[Link]}
</div>
}
export default App
Step 2 - Cleaning the hook to include a
loading parameter
What if you want to show a loader when the data is not yet
fetched from the backend?
import { useEffect, useState } from 'react'
import axios from 'axios'
function useTodos() {
const [loading, setLoading] = useState(true);
const [todos, setTodos] = useState([])
useEffect(() => {
[Link]("[Link]
.then(res => {
setTodos([Link]);
setLoading(false);
})
}, [])
return {
todos: todos,
loading: loading
};
[Link] 8/19
10/11/2024, 01:26 Projects | 100xDevs
Custom Hooks 3 of 5
function App() {
const { todos, loading } = useTodos();
if (loading) {
return <div>
Loading...
</div>
}
return (
<>
{[Link](todo => <Track todo={todo} />)}
</>
)
}
function Track({ todo }) {
return <div>
{[Link]}
<br />
{[Link]}
</div>
}
export default App
Step 3 - Auto refreshing hook
What if you want to keep polling the backend every n seconds?
n needs to be passed in as an input to the hook
import { useEffect, useState } from 'react'
import axios from 'axios'
function useTodos(n) {
const [loading, setLoading] = useState(true);
const [todos, setTodos] = useState([])
function getData() {
[Link] 9/19
10/11/2024, 01:26 Projects | 100xDevs
[Link]("[Link]
.then(res => {
Custom Hooks 3 of 5
setTodos([Link]);
setLoading(false);
})
}
useEffect(() => {
setInterval(() => {
getData();
}, n * 1000)
getData();
}, [n])
return {
todos: todos,
loading: loading
};
}
function App() {
const { todos, loading } = useTodos(5);
if (loading) {
return <div>
Loading...
</div>
}
return (
<>
{[Link](todo => <Track todo={todo} />)}
</>
)
}
function Track({ todo }) {
return <div>
{[Link]}
<br />
{[Link]}
</div>
}
[Link] 10/19
10/11/2024, 01:26 Projects | 100xDevs
export default App
Custom Hooks 3 of 5
Final solution
import { useEffect, useState } from 'react'
import axios from 'axios'
function useTodos(n) {
const [todos, setTodos] = useState([])
const [loading, setLoading] = useState(true);
useEffect(() => {
const value = setInterval(() => {
[Link]("[Link]
.then(res => {
setTodos([Link]);
setLoading(false);
})
}, n * 1000)
[Link]("[Link]
.then(res => {
setTodos([Link]);
setLoading(false);
})
return () => {
clearInterval(value)
}
}, [n])
return {todos, loading};
}
function App() {
const {todos, loading} = useTodos(10);
if (loading) {
return <div> loading... </div>
}
[Link] 11/19
10/11/2024, 01:26 Projects | 100xDevs
return (
<>
Custom Hooks 3 of 5
{[Link](todo => <Track todo={todo} />)}
</>
)
}
function Track({ todo }) {
return <div>
{[Link]}
<br />
{[Link]}
</div>
}
export default App
swr - React Hooks for Data
Fetching
swr is a popular React library that creates a lot of these hooks for
you, and you can use it directly.
For example -
import useSWR from 'swr'
// const fetcher = (url) => fetch(url).then((res) => [Link]());
const fetcher = async function(url) {
const data = await fetch(url);
const json = await [Link]();
return json;
};
function Profile() {
const { data, error, isLoading } = useSWR('[Link]
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
[Link] 12/19
10/11/2024, 01:26 Projects | 100xDevs
return <div>hello, you have {[Link]} todos!</div>
}
Custom Hooks 3 of 5
[Link]
4 - Browser functionality
related hooks
1. useIsOnline hook
Create a hook that returns true or false based on weather the
user is currently online
You are given that -
1. [Link] returns true or false based on
weather the user is online
2. You can attach the following event listeners to listen to
weather the user is online or not
[Link]('online', () => [Link]('Became online
[Link]('offline', () => [Link]('Became offline
Solution
import { useEffect, useState } from 'react'
function useIsOnline() {
const [isOnline, setIsOnline] = useState([Link]
useEffect(() => {
[Link] 13/19
10/11/2024, 01:26 Projects | 100xDevs
[Link]('online', () => setIsOnline(true));
[Link]('offline', () => setIsOnline(false));
Custom Hooks 3 of 5
}, [])
return isOnline;
}
function App() {
const isOnline = useIsOnline(5);
return (
<>
{isOnline ? "You are online yay!" : "You are not online"}
</>
)
}
export default App
2. useMousePointer hook
Create a hook that returns you the current mouse pointer
position.
The final react app that uses it looks like this
[Link] 14/19
10/11/2024, 01:26 Projects | 100xDevs
Custom Hooks 3 of 5
You are given that
[Link]('mousemove', handleMouseMove);
will trigger the handleMouseMove function anytime the mouse
pointer is moved.
Solution
import { useEffect, useState } from 'react'
const useMousePointer = () => {
const [position, setPosition] = useState({ x: 0, y: 0 });
const handleMouseMove = (e) => {
setPosition({ x: [Link], y: [Link] });
};
useEffect(() => {
[Link]('mousemove', handleMouseMove);
return () => {
[Link]('mousemove', handleMouseMo
};
}, []);
return position;
};
function App() {
const mousePointer = useMousePointer();
return (
<>
Your mouse position is {mousePointer.x} {mousePointer.y}
</>
[Link] 15/19
10/11/2024, 01:26 Projects | 100xDevs
)
}
Custom Hooks 3 of 5
export default App
5 - Performance/Timer
based
1. useInterval
Create a hook that runs a certain callback function every n
seconds.
You have to implement useInterval which is being used in the
code below -
import { useEffect, useState } from 'react';
function App() {
const [count, setCount] = useState(0);
useInterval(() => {
setCount(c => c + 1);
}, 1000)
return (
<>
Timer is at {count}
[Link] 16/19
10/11/2024, 01:26 Projects | 100xDevs
</>
)
Custom Hooks 3 of 5
}
export default App
Final app should look like this
Solution
const useInterval = (callback, delay) => {
useEffect(() => {
const intervalId = setInterval(callback, delay);
return () => clearInterval(intervalId);
}, [callback, delay]);
};
2. useDebounce
Create a hook that debounces a value given
1. The value that needs to be debounced
2. The interval at which the value should be debounced.
import React, { useState } from 'react';
import useDebounce from './useDebounce';
[Link] 17/19
10/11/2024, 01:26 Projects | 100xDevs
const SearchBar = () => {
const [inputValue, setInputValue] = useState('');
Custom Hooks 3 of 5
const debouncedValue = useDebounce(inputValue, 500); // 500
// Use the debouncedValue in your component logic, e.g., trigger
return (
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue([Link])}
placeholder="Search..."
/>
);
};
export default SearchBar;
Solution
import { useState, useEffect } from 'react';
const useDebounce = (value, delay) => {
// State to store the debounced value
const [debouncedValue, setDebouncedValue] = useState(val
useEffect(() => {
// Set up a timer to update the debounced value after the sp
const timerId = setTimeout(() => {
setDebouncedValue(value);
}, delay);
// Clean up the timer if the value changes before the delay h
return () => clearTimeout(timerId);
}, [value, delay]);
return debouncedValue;
};
[Link] 18/19
10/11/2024, 01:26 Projects | 100xDevs
Custom Hooks 3 of 5
[Link] 19/19