React Hook
React Hook
useState
useState
is a Hook that lets you add state to functional components. It returns the current state and a function to update that state.
Example
import React, { useState } from 'react';
function Example() {
// Declare a state variable named "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect
useEffect
is a Hook that allows you to perform side effects in functional components, such as data fetching, subscriptions, or manually manipulating the DOM. It covers lifecycle methods similar to componentDidMount, componentDidUpdate, and componentWillUnmount in class components.
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
document.title = `You clicked ${count} times`;
// Cleanup function (similar to componentWillUnmount):
return () => {
document.title = 'Default Title';
};
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useContext
useContext
is a Hook that lets you read context and subscribe to context changes. This can be useful for accessing global values like user authentication status, themes, etc., without prop drilling.
Example
import React, { useContext } from 'react';
import ThemeContext from './ThemeContext'; // Assume this is a predefined context
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
Themed Button
</button>
);
}
useReducer
useReducer
is often used for managing complex state logic that involves multiple sub-values or when the next state depends on the previous one. It's also useful for handling events with payloads.
Example
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</>
);
}
useCallback
useCallback
returns a memoized version of the callback function that only changes if one of its dependencies has changed. This is useful for optimizing performance by preventing unnecessary renders.
Example
import React, { useState, useCallback } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Clicked');
}, []); // Empty dependency array means the callback will not change
return (
<ChildComponent onClick={handleClick} />
);
}
function ChildComponent({ onClick }) {
// ChildComponent will not re-render unnecessarily due to stable onClick
return <button onClick={onClick}>Click Me</button>;
}
useMemo
useMemo
returns a memoized value. Use this hook to optimize performance by avoiding expensive calculations on every render.
Example
import React, { useState, useMemo } from 'react';
function Calculator() {
const [number, setNumber] = useState(1);
const expensiveCalculation = useMemo(() => {
// Simulate an expensive calculation
let sum = 0;
for (let i = 0; i <= number; i++) {
sum += i;
}
return sum;
}, [number]); // Only recalculate when number changes
return (
<div>
<input type="number" value={number} onChange={(e) => setNumber(Number(e.target.value))} />
<p>Expensive Calculation Result: {expensiveCalculation}</p>
</div>
);
}
useRef
useRef
provides a way to access DOM nodes or keep mutable variables across renders. Unlike useState
, updates to ref.current
do not trigger re-renders.
Example
import React, { useRef } from 'react';
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}