React Hooks are a relatively new addition to React library. They allow us to use state and other React features without having to use class components or write boilerplate code.In this article, we will take a deep dive into most commonly used React Hooks are shown in table of contents.
•useState
The useState Hook allows us to add state to our functional components. It takes an initial state value as a parameter and returns an array containing the current state value and a function to update the state.
Example:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={increment}>Click me</button>
</div>
);
}
•useEffect
The useEffect Hook allows us to perform side effects in our functional components. It takes a function as a parameter and runs it after the component has been rendered.
Example:
import React, { useState, useEffect } from 'react';
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
function increment() {
setCount(count + 1);
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={increment}>Click me</button>
</div>
);
}
•useContext
The useContext Hook allows us to use context in our functional components. It takes a context object as a parameter and returns the current context value.
Example:
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return (
<div>
<button style={{ background: theme === 'dark' ? 'black' : 'white', color: theme === 'dark' ? 'white' : 'black' }}>
{theme === 'dark' ? 'Dark' : 'Light'}
</button>
</div>
);
}
•useReducer
The useReducer Hook allows us to use a reducer function to manage state in our functional components. It takes a reducer function and an initial state value as parameters and returns an array containing the current state value and a dispatch function to update the state.
Example:
import React, { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return state + 1;
case 'decrement':
return state - 1;
default:
throw new Error();
}
}
function Counter() {
const [count, dispatch] = useReducer(reducer, 0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
•useCallback
The useCallback Hook allows us to memoize a function and prevent it from being recreated on every render. It takes a function and an array of dependencies as parameters and returns a memoized function.
Example:
import React, { useState, useCallback } from 'react';
function App() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={increment}>Click me</button>
</div>
);
}
•useMemo
The useMemo Hook allows us to memoize a value and prevent it from being recalculated on every render. It takes a function and an array of dependencies as parameters and returns a memoized value.
Example:
import React, { useState, useMemo } from 'react';
function App() {
const [count, setCount] = useState(0);
const doubleCount = useMemo(() => {
return count * 2;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<p>Double count: {doubleCount}</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
•useRef
The useRef Hook allows us to create a mutable variable that persists across renders. It returns an object with a current property that we can set and get the value of.
Example:
import React, { useRef } from 'react';
function App() {
const inputRef = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
alert(inputRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<button type="submit">Submit</button>
</form>
);
}
•useLayoutEffect
The useLayoutEffect Hook is similar to useEffect, but it runs synchronously after all DOM mutations are processed. This makes it useful for measuring layout and performing animations.
Example:
import React, { useState, useLayoutEffect } from 'react';
function App() {
const [width, setWidth] = useState(0);
useLayoutEffect(() => {
setWidth(document.documentElement.clientWidth);
}, []);
return (
<div>
<p>Window width: {width}</p>
</div>
);
}
•useImperativeHandle
The useImperativeHandle Hook allows us to customize the instance value that is exposed to parent components when using ref. It takes a ref and a function that returns an object as parameters.
Example:
import React, { useRef, useImperativeHandle } from 'react';
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} />;
}
FancyInput = React.forwardRef(FancyInput);
function App() {
const inputRef = useRef();
const handleClick = () => {
inputRef.current.focus();
};
return (
<div>
<FancyInput ref={inputRef} />
<button onClick={handleClick}>Focus</button>
</div>
);
}
•useMemo vs useCallback
Both useMemo and useCallback allow us to memoize values and functions, respectively, and prevent them from being recalculated or recreated on every render. The difference is that useMemo returns a memoized value, while useCallback returns a memoized function.
Use useMemo when:
- You need to memoize a value, not a function
- The calculation is expensive and you want to prevent it from being recalculated on every render
- The value is not dependent on any prop or state changes
Use useCallback when:
- You need to memoize a function, not a value
- The function is expensive to create and you want to prevent it from being recreated on every render
- The function is passed down to child components as a prop and you want to prevent unnecessary renders
- The function relies on some dependencies, such as props or state, that may change frequently
•useDebugValue
The useDebugValue Hook allows us to display custom debugging information for a Hook in the React DevTools. It takes a value as parameter and a formatting function that formats the value for display.
Example:
import React, { useState, useDebugValue } from 'react';
function useCounter(initialValue) {
const [count, setCount] = useState(initialValue);
useDebugValue(count, count => `Count: ${count}`);
return [count, () => setCount(count + 1)];
}
function App() {
const [count, increment] = useCounter(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
•Custom Hooks
Custom Hooks are a way to reuse stateful logic across components. They are normal JavaScript functions that use one or more of the built-in Hooks and return a stateful value and/or functions to update that value.
Example:
import { useState, useEffect } from 'react';
function useMousePosition() {
const [position, setPosition] = useState({ x: 0, y: 0 });
function handleMouseMove(e) {
setPosition({ x: e.clientX, y: e.clientY });
}
useEffect(() => {
window.addEventListener('mousemove', handleMouseMove);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
};
}, []);
return position;
}
function App() {
const { x, y } = useMousePosition();
return (
<div>
<p>The mouse position is ({x}, {y})</p>
</div>
);
}
•Conclusion
React Hooks are a powerful and flexible way to manage state and side effects in functional components. They allow us to write more concise and reusable code, and to share stateful logic between components. By using the built-in Hooks and creating custom Hooks, we can create complex and dynamic user interfaces with ease.
React Hooks are a powerful and flexible way to manage state and side effects in functional components. They allow us to write more concise and reusable code, and to share stateful logic between components. By using the built-in Hooks and creating custom Hooks, we can create complex and dynamic user interfaces with ease.
While Hooks are a great addition to React, they are not always necessary or appropriate. Class components still have their place, especially in legacy code or in cases where we need to leverage their full lifecycle methods or access to the DOM. Additionally, Hooks are not a replacement for good programming practices, such as code organization, separation of concerns, and testing.
It is important to use Hooks responsibly and to understand their limitations and tradeoffs. By doing so, we can take advantage of their benefits and create better React applications.
Comments
Post a Comment
Hello,
Thank you for taking the time to leave a comment! Your feedback is important to us and we appreciate any suggestions or thoughts you may have. We strive to create the best possible experience for our users and your comments will help us achieve that goal.
If you have any questions or concerns, please don't hesitate to reach out to us. We're here to help and are always happy to hear from our users.
Thank you again for your comment and have a great day!
Best regards,
NewWebSofts