React

React is a library for building user interfaces. React is not a framework - it's not even exclusive to the web. It's used with other libraries to render to certain environments. For instance, React Native can be used to build mobile applications.

React Hooks Read More

React Hooks let developers utilize state and other React features without class components.

useState

This hook lets you add state to functional components. It provides a way to manage local state in a component and will re-render the component when the state changes.


                            const [count, setCount] = useState(0);
                            // ...
                            <button onClick={() => setCount(count + 1)}>Increment</button>
                        
useEffect

It is similar to combining componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods in class components. It runs side effects after render.


                            useEffect(() => {
                                document.title = `Clicked ${count} times`;
                            }, [count]);
                        
useContext

Allows you to avoid prop-drilling by passing data directly to any child component. This is useful for sharing values like themes, authentication status, etc.


                            const ThemeContext = React.createContext('light');
                            const theme = useContext(ThemeContext);
                            <div className={theme}>...</div>
                        
useReducer

An alternative to useState. It's preferable when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one.


                            const initialState = {count: 0};
                            function reducer(state, action) {
                            switch (action.type) {
                                case 'increment': return {count: state.count + 1};
                                default: throw new Error();
                            }
                            }
                            const [state, dispatch] = useReducer(reducer, initialState);
                        
useCallback

Returns a memoized version of the callback that only changes if one of the dependencies has changed. Useful for optimizing performance.


                            const memoizedCallback = useCallback(
                            () => {
                                doSomething(a, b);
                            },
                            [a, b],
                            );
                        
useMemo

Like useCallback but for any computed value.


                            const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
                        
useRef

Useful for accessing the DOM directly or keeping any mutable value around (like instance variables in class components).


                            const inputRef = useRef(null);
                            <input ref={inputRef} />
                        
useImperativeHandle

Customizes the instance value that is exposed when using React.forwardRef.


                            useImperativeHandle(ref, () => ({
                            focus: () => {
                                inputRef.current.focus();
                            }
                            }));
                        
useLayoutEffect

Similar to useEffect, but it fires synchronously after all DOM mutations. Useful for reading layout from the DOM and synchronously re-rendering.


                            useLayoutEffect(() => {
                            // Read layout from the DOM and synchronously re-render
                            });
                        
useDebugValue

Display a label for custom hooks in React DevTools.


                            useDebugValue('Description for DevTools');
                        

The useMemo hook is used to memoize expensive calculations in a functional component. "Memoize" means storing the results of expensive function calls and returning the cached result when the same inputs occur again. This optimization helps to ensure that these operations don't run on every render unless necessary.

Consider we have an array of numbers and we want to find the sum of these numbers. Without useMemo, the sum would be recalculated every time the component renders, regardless of whether the array has changed. This can be inefficient.

Bad Example:

Using a direct computation in the component without useMemo to calculate the sum. The sum is recalculated every time the component re-renders, even if the numbers haven't changed.


                            import React from 'react';
                            
                            function NumberComponent(props) {
                                const numbers = props.numbers;
                            
                                const sum = numbers.reduce((acc, num) => acc + num, 0);
                            
                                return (
                                    <div>
                                        <h2>Sum of numbers: {sum}</h2>
                                    </div>
                                );
                            }
                        

However, with useMemo, you can optimize the component so that the sum is recalculated only when the numbers change:

Optimized Example using useMemo:

Using useMemo to memoize the sum calculation. The sum is recalculated only when the numbers change.


                            import React, { useMemo } from 'react';
                            
                            function NumberComponent(props) {
                                const numbers = props.numbers;
                            
                                const sum = useMemo(() => {
                                    console.log('Calculating sum...');
                                    return numbers.reduce((acc, num) => acc + num, 0);
                                }, [numbers]);
                            
                                return (
                                    <div>
                                        <h2>Sum of numbers: {sum}</h2>
                                    </div>
                                );
                            }
                        

In this optimized example, the console.log statement will only execute when the numbers array changes, demonstrating the power and efficiency of useMemo.