ullas kunder

Designer & Developer

Essential React Hooks

useState:

  • useState allows you to add state to functional components.
  • It returns an array with two elements: the current state value and a function to update it.
  • Example:

    import React, { useState } from "react";
    
    const Counter = () => {
      const [count, setCount] = useState(0);
    
      const increment = () => {
        setCount(count + 1);
      };
    
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={increment}>Increment</button>
        </div>
      );
    };

useEffect:

  • useEffect allows you to perform side effects in functional components.
  • It replaces componentDidMount, componentDidUpdate, and componentWillUnmount.
  • Example:

    import React, { useState, useEffect } from "react";
    
    const DataFetcher = () => {
      const [data, setData] = useState(null);
    
      useEffect(() => {
        fetchData().then((result) => {
          setData(result);
        });
      }, []);
    
      return <div>{data}</div>;
    };

useContext:

  • useContext allows you to access the nearest context's value.
  • It replaces the need for context consumers.
  • Example:

    import React, { useContext } from "react";
    
    const ThemeContext = React.createContext("light");
    
    const ThemeConsumer = () => {
      const theme = useContext(ThemeContext);
    
      return <div>Current theme: {theme}</div>;
    };

useReducer:

  • useReducer is an alternative to useState when state logic is complex.
  • It allows you to manage state with a reducer function, similar to Redux.
  • Example:

    import React, { useReducer } from "react";
    
    const initialState = { count: 0 };
    
    const reducer = (state, action) => {
      switch (action.type) {
        case "increment":
          return { count: state.count + 1 };
        case "decrement":
          return { count: state.count - 1 };
        default:
          throw new Error();
      }
    };
    
    const Counter = () => {
      const [state, dispatch] = useReducer(reducer, initialState);
    
      const increment = () => {
        dispatch({ type: "increment" });
      };
    
      const decrement = () => {
        dispatch({ type: "decrement" });
      };
    
      return (
        <div>
          <p>Count: {state.count}</p>
          <button onClick={increment}>Increment</button>
          <button onClick={decrement}>Decrement</button>
        </div>
      );
    };

useRef:

  • useRef allows you to persist a value across renders without triggering a re-render.
  • It can be used to access the DOM or store mutable values.
  • Example:

    import React, { useRef } from "react";
    
    const InputWithFocus = () => {
      const inputRef = useRef(null);
    
      const focusInput = () => {
        inputRef.current.focus();
      };
    
      return (
        <div>
          <input ref={inputRef} />
          <button onClick={focusInput}>Focus Input</button>
        </div>
      );
    };

useMemo:

  • useMemo allows you to memoize expensive calculations and avoid unnecessary re-computations.
  • It takes a function and a dependencies array and returns the memoized value.
  • Example:

    import React, { useMemo } from "react";
    
    const ExpensiveCalculation = ({ a, b }) => {
      const result = useMemo(() => {
        // Perform expensive calculation using a and b
        return a * b;
      }, [a, b]);
    
      return <div>Result: {result}</div>;
    };

useCallback:

  • useCallback allows you to memoize functions and prevent unnecessary re-renders.
  • It takes a function and a dependencies array and returns the memoized function.
  • Example:

    import React, { useCallback } from "react";
    
    const MemoizedButton = ({ onClick }) => {
      const memoizedOnClick = useCallback(() => {
        // Do something when the button is clicked
        onClick();
      }, [onClick]);
    
      return <button onClick={memoizedOnClick}>Click me</button>;
    };

useLayoutEffect:

  • useLayoutEffect is similar to useEffect but fires synchronously after all DOM mutations.
  • It can be used when you need to read or manipulate the DOM immediately after the component has updated.
  • Example:

    import React, { useLayoutEffect } from "react";
    
    const LogWindowDimensions = () => {
      useLayoutEffect(() => {
        const handleResize = () => {
          // Log window dimensions
          console.log(window.innerWidth, window.innerHeight);
        };
    
        window.addEventListener("resize", handleResize);
        return () => {
          window.removeEventListener("resize", handleResize);
        };
      }, []);
    
      return <div>Check the console for window dimensions</div>;
    };

useImperativeHandle:

  • useImperativeHandle allows you to customize the instance value that is exposed to parent components when using ref forwarding.
  • It is typically used in conjunction with forwardRef.
  • Example:

    import React, { useImperativeHandle, forwardRef } from "react";
    
    const CustomInput = forwardRef((props, ref) => {
      const inputRef = useRef(null);
    
      useImperativeHandle(ref, () => ({
        focus: () => {
          inputRef.current.focus();
        },
        // More custom methods...
      }));
    
      return <input ref={inputRef} />;
    });
    
    // Usage in a parent component:
    const ParentComponent = () => {
      const inputRef = useRef(null);
    
      const handleClick = () => {
        inputRef.current.focus();
      };
    
      return (
        <div>
          <CustomInput ref={inputRef} />
          <button onClick={handleClick}>Focus Input</button>
        </div>
      );
    };

useDebugValue:

  • useDebugValue is a custom hook that can be used to display a label for custom hooks in React DevTools.
  • It can be helpful for debugging and inspecting custom hooks.

    • Example:

      import { useDebugValue } from "react";
      
      const useCustomHook = () => {
        // Custom hook logic...
      
        useDebugValue("Custom Hook Label");
      };

useErrorBoundary:

  • useErrorBoundary is a hook for creating error boundaries within functional components.
  • It allows you to catch and handle errors within a component tree.

    • Example:

      import React, { useErrorBoundary } from "react";
      
      const ErrorBoundaryComponent = ({ children }) => {
        const [error, resetErrorBoundary] = useErrorBoundary();
      
        if (error) {
          // Render an error component or fallback UI
          return (
            <div>
              <p>An error occurred.</p>
              <button onClick={resetErrorBoundary}>Try again</button>
            </div>
          );
        }
      
        return children;
      };

useTransition:

  • useTransition is a hook for managing and coordinating transitions and animations.
  • It allows you to batch multiple state updates and defer rendering updates until after a certain time.

    • Example:

      import React, { useState, useTransition } from "react";
      
      const AnimatedText = () => {
        const [text, setText] = useState("");
        const [startTransition, isPending] = useTransition();
      
        const handleClick = () => {
          startTransition(() => {
            setText("New text");
          });
        };
      
        return (
          <div>
            {isPending ? "Loading..." : text}
            <button onClick={handleClick}>Load Text</button>
          </div>
        );
      };

useDeferredValue:

- useDeferredValue is a hook that allows you to defer the update of a value until after a certain time.
- It can be useful for optimizing performance in specific scenarios.
- Example:
  ```jsx
  import React, { useState, useDeferredValue } from 'react';

  const DeferredValueExample = () => {
    const [value, setValue] = useState('');

    const deferredValue = useDeferredValue(value, { timeoutMs: 1000 });

    const handleChange = (event) => {
      setValue(event.target.value);
    };

    return (
      <div>
        <input value={value} onChange={handleChange} />
        <p>Deferred Value: {deferredValue}</p>
      </div>
    );
  };
  ```

useOpaqueIdentifier:

- useOpaqueIdentifier is a hook that generates a unique identifier for a component instance.
- It can be used as a key in lists to improve rendering performance.
- Example:
  ```jsx
  import React, { useOpaqueIdentifier } from 'react';

  const ListItem = ({ item }) => {
    const id = useOpaqueIdentifier();

    return <div key={id}>{item}</div>;
  };
  ```

useTransitionEffect:

  • useTransitionEffect is a combination of useEffect and useTransition.
  • It allows you to create transitions that occur over a certain period of time.

    • Example:

      import React, { useState, useTransitionEffect } from "react";
      
      const FadeInOutComponent = () => {
        const [show, setShow] = useState(false);
        const [startTransition, isPending] = useTransition();
      
        useTransitionEffect(() => {
          if (show) {
            startTransition(() => {
              // Perform fade-in animation
            });
          } else {
            startTransition(() => {
              // Perform fade-out animation
            });
          }
        }, [show]);
      
        const handleClick = () => {
          setShow((prevShow) => !prevShow);
        };
      
        return (
          <div>
            {isPending ? "Animating..." : show ? "Visible" : "Hidden"}
            <button onClick={handleClick}>Toggle Visibility</button>
          </div>
        );
      };