Quick revision - rs-hash/Senior GitHub Wiki
- React hooks are a set of functions provided by React to add stateful logic and side effects to functional components.
- They were introduced in React 16.8 and allow developers to use state and other React features without writing a class.
- Hooks can be only called in react function components and cannot be conditional and must be called at the top level of a function component or another custom hook.
- But the new
usehook (React 19 canary) can be called within loops and conditional statements like if. - Lifecycle methods are available only in class components and be used to manage state in various stages of the component's lifecycle.
- The useState hook in React is used to manage state in functional components, while class components use this.state and this.setState() for state management.
- State updates using (useState functional components) setCount(newValue) do not merge state and replace the entire state object with the new value.
- State updates are done using this.setState({ ... }) ( class components ), which merges the new state with the existing state.
- useState: Generally considered more performant because it doesn't involve class instantiation overhead and functional components are optimized by React.
- Class Component: May have a slight performance overhead due to the class instantiation and lifecycle methods.
/*useState hook*/
const [count, setCount] = useState(0);
<button onClick={() => setCount(count + 1)}>Increment</button>
/*class components state*/
this.state = { count: 0 };
<button onClick={() => this.setState({ count: this.state.count + 1 })}>Increment</button>- The convention is to name state variables like [something, setSomething] using array destructuring.
- initialState: The value you want the state to be initially. It can be a value of any type, but there is a special behavior for functions. This argument is ignored after the initial render.
- If you pass a function as initialState, it will be treated as an initializer function. It should be pure, should take no arguments, and should return a value of any type. React will call your initializer function when initializing the component, and store its return value as the initial state
- useState returns an array with exactly two values: current state & set function
- The current state. During the first render, it will match the initialState you have passed.
- The set function that lets you update the state to a different value and trigger a re-render.
- In Strict Mode, React will call your initializer function twice in order to help you find accidental impurities.
- If the new value you provide is identical to the current state, as determined by an Object.is comparison, React will skip re-rendering the component and its children.
- React batches state updates. It updates the screen after all the event handlers have run and have called their set functions. This prevents multiple re-renders during a single event. In the rare case that you need to force React to update the screen earlier, for example to access the DOM, you can use flushSync.
- Better to pass the initializer function, it is performant when compared to passing initializer state directly
/*only runs during initialization. It does not run when component re-renders, such as when you type into the input.*/
const [todos, setTodos] = useState(createInitialTodos);
/*not optimized, function runs on every render, such as when you type into the input */
const [todos, setTodos] = useState(createInitialTodos());- You can reset a component’s state by passing a different key to a component
-
useEffect is a React Hook that lets you synchronize a component with an external system.
-
useEffect(setup, dependencies?) -
When your component is added to the DOM, React will run your setup function. After every re-render with changed dependencies, React will first run the cleanup function (if you provided it) with the old values, and then run your setup function with the new values. After your component is removed from the DOM, React will run your cleanup function.
-
The list of dependencies must have a constant number of items and be written inline like [dep1, dep2, dep3]. React will compare each dependency with its previous value using the Object.is comparison. If you omit this argument, your Effect will re-run after every re-render of the component.
-
If there is no external system involved (for example, if you want to update a component’s state when some props or state change), you shouldn’t need an Effect. Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone.
-
Avoid: Adjusting state on prop change in an Effect
/*AVOID */
function List({ items }) {
const [isReverse, setIsReverse] = useState(false);
const [selection, setSelection] = useState(null);
// 🔴 Avoid: Adjusting state on prop change in an Effect
useEffect(() => {
setSelection(null);
}, [items]);
// ...
}
/*USE*/
function List({ items }) {
const [isReverse, setIsReverse] = useState(false);
const [selection, setSelection] = useState(null);
// Better: Adjust the state while rendering
const [prevItems, setPrevItems] = useState(items);
if (items !== prevItems) {
setPrevItems(items);
setSelection(null);
}
// ...
}- If this logic is caused by a particular interaction, keep it in the event handler. If it’s caused by the user seeing the component on the screen, keep it in the Effect.
- You can fetch data with Effects, but you need to implement cleanup to avoid race conditions.
- The useEffect hook enables the management of side effects in functional components. It is used to perform actions after the component has rendered or to handle cleanup tasks when the component unmounts.
- useEffect is a hook in React that allows you to perform side effects in functional components. Side effects can include data fetching, subscriptions, manual DOM manipulation, and more.
- useEffect is similar to lifecycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount in class components, but it's designed specifically for functional components.
- Functional Component (useEffect): You specify the dependencies in the dependency array. If the dependency array is empty ([]), the effect runs only once after the component mounts (like componentDidMount in class components). If you include dependencies, the effect runs whenever any of the dependencies change (like componentDidUpdate with specific conditions).
- Class Component (componentDidMount, componentDidUpdate): componentDidMount runs after the component mounts, componentDidUpdate runs after every update, and componentWillUnmount runs before the component unmounts.
- In functional components with useEffect, to access previous props or state, you can use the functional update form of useState or useRef hooks.
const [prevProps, setPrevProps] = useState(null);
useEffect(() => {
setPrevProps(props);
}, [props]);useContext: The useContext hook provides a way to consume values from React's Context API within functional components. It allows you to access and update context values without using higher-order components or render props.
useReducer: The useReducer hook is an alternative to useState for managing complex state logic that involves multiple actions. It follows the same pattern as Redux reducers.
useCallback: The useCallback hook is used to memoize functions to prevent unnecessary re-renders when passing them down as props to child components.
useMemo: The useMemo hook is used to memoize the result of a function, preventing expensive calculations from being re-computed on every render.
useRef: The useRef hook is used to create mutable references that persist across renders. It is commonly used to access and manipulate DOM elements.
useImperativeHandle: The useImperativeHandle hook allows a parent component to interact with child components that are using forward refs.
useLayoutEffect: The useLayoutEffect hook is similar to useEffect, but it runs synchronously after all DOM mutations. It is useful when you need to measure or manipulate DOM elements before the browser repaints.
useDebugValue: The useDebugValue hook is used to display custom labels in React DevTools when inspecting hooks.