CORE REACT - rs-hash/Senior GitHub Wiki

HOOKS

Hooks let you use different React features from your components. You can either use the built-in Hooks or combine them to build your own. This page lists all built-in Hooks in React.

State Hooks

To add state to a component, use one of these Hooks:

Context Hooks

Ref-Hooks

  • Refs let a component hold some information that isn’t used for rendering, like a DOM node or a timeout ID. Unlike with state, updating a ref does not re-render your component. Refs are an “escape hatch” from the React paradigm. They are useful when you need to work with non-React systems, such as the built-in browser APIs.
  • useRef declares a ref. You can hold any value in it, but most often it’s used to hold a DOM node.
  • useImperativeHandle lets you customize the ref exposed by your component. This is rarely used.

Effect Hooks

  • useEffect connects a component to an external system
  • Effects are an “escape hatch” from the React paradigm. Don’t use Effects to orchestrate the data flow of your application. If you’re not interacting with an external system, you might not need an Effect.

  • There are two rarely used variations of useEffect with differences in timing:

  • useLayoutEffect fires before the browser repaints the screen. You can measure layout here.
  • useInsertionEffect fires before React makes changes to the DOM. Libraries can insert dynamic CSS here.

Performance Hooks

  • A common way to optimize re-rendering performance is to skip unnecessary work. For example, you can tell React to reuse a cached calculation or to skip a re-render if the data has not changed since the previous render.

  • To skip calculations and unnecessary re-rendering, use one of these Hooks:

  • useMemo lets you cache the result of an expensive calculation.
  • useCallback lets you cache a function definition before passing it down to an optimized component.
  • Sometimes, you can’t skip re-rendering because the screen actually needs to update. In that case, you can improve performance by separating blocking updates that must be synchronous (like typing into an input) from non-blocking updates which don’t need to block the user interface (like updating a chart).

  • To prioritize rendering, use one of these Hooks:

  • useTransition lets you mark a state transition as non-blocking and allow other updates to interrupt it.
  • useDeferredValue lets you defer updating a non-critical part of the UI and let other parts update first.

Resource Hooks

  • Resources can be accessed by a component without having them as part of their state. For example, a component can read a message from a Promise or read styling information from a context.

  • To read a value from a resource, use this Hook:

function MessageComponent({ messagePromise }) {
  const message = use(messagePromise);
  const theme = use(ThemeContext);
  // ...
}

Other Hooks

  • These Hooks are mostly useful to library authors and aren’t commonly used in the application code.
  • useDebugValue lets you customize the label React DevTools displays for your custom Hook.
  • useId lets a component associate a unique ID with itself. Typically used with accessibility APIs.
  • useSyncExternalStore lets a component subscribe to an external store.

Other Core React Topics

SHORT CONCEPTS

State Hooks

useState

  • 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
  • The set function only updates the state variable for the next render. If you read the state variable after calling the set function, you will still get the old value that was on the screen before your call.
  • You can reset a component’s state by passing a different key to a component.
  • Calling the set function does not change the current state in the already executing code:It only affects what useState will return starting from the next render.
/* Functions */

 const calculateInitialValue = () => {
    // Simulate expensive computation
    let sum = 0;
    for (let i = 0; i < 1000000; i++) {
      sum += i;
    }
    return sum;
  };

  const [value, setValue] = useState(() => calculateInitialValue());

useReducer

Performance hooks

  • useMemo lets you cache the result of an expensive calculation.
  • useCallback lets you cache a function definition before passing it down to an optimized component.

useMemo

useMemo is a React Hook that lets you cache the result of a calculation between re-renders.

  • Pass a calculation function you need to render, and a dependency array

when to use

  • If a calculation takes more than 1ms, makes sense to memo that value
  • useMemo won’t make the first render faster. It only helps you skip unnecessary work on updates. - CPU throttling to check if it works

Optimizing with useMemo is only valuable in a few cases:

  • The calculation you’re putting in useMemo is noticeably slow, and its dependencies rarely change.
  • You pass it as a prop to a component wrapped in memo. You want to skip re-rendering if the value hasn’t changed. Memoization lets your component re-render only when dependencies aren’t the same.
  • The value you’re passing is later used as a dependency of some Hook. For example, maybe another useMemo calculation value depends on it. Or maybe you are depending on this value from useEffect.

In practice, you can make a lot of memoization unnecessary by following a few principles:

  • When a component visually wraps other components, let it accept JSX as children. This way, when the wrapper component updates its own state, React knows that its children don’t need to re-render.

useCallback

useCallback is a React Hook that lets you cache a function definition between re-renders.

You need to pass two things to useCallback:

  • A function definition that you want to cache between re-renders.
  • A list of dependencies including every value within your component that’s used inside your function.
  • On the following renders, React will compare the dependencies with the dependencies you passed during the previous render. If none of the dependencies have changed (compared with Object.is), useCallback will return the same function as before. Otherwise, useCallback will return the function you passed on this render.
  • lets say if we pass a function down to a child component, By default, when a component re-renders, React re-renders all of its children recursively. This is fine for components but if it's slow, we can wrap the child in memo. with this change React will skip re-rendering if all of its props are the same as on the last render. This is when caching a function becomes important! Let’s say you defined handleSubmit without useCallback: In JavaScript, a function () {} or () => {} always creates a different function, similar to how the {} object literal always creates a new object. Normally, this wouldn’t be a problem, but it means that ShippingForm props will never be the same, and your memo optimization won’t work. This is where useCallback comes in handy: By wrapping the function in useCallback, you ensure that it’s the same function between the re-renders (until dependencies change). You don’t have to wrap a function in useCallback unless you do it for some specific reason. In this example, the reason is that you pass it to a component wrapped in memo, and this lets it skip re-rendering

Caching a function with useCallback is only valuable in a few cases:

  • You pass it as a prop to a component wrapped in memo. You want to skip re-rendering if the value hasn’t changed. Memoization lets your component re-render only if dependencies changed.
  • The function you’re passing is later used as a dependency of some Hook. For example, another function wrapped in useCallback depends on it, or you depend on this function from useEffect.
  • If you’re writing a custom Hook, it’s recommended to wrap any functions that it returns into useCallback:
  • useCallback does not prevent creating the function. You’re always creating a function (and that’s fine!), but React ignores it and gives you back a cached function if nothing changed.

In practice, you can make a lot of memoization unnecessary by following a few principles:

  • When a component visually wraps other components, let it accept JSX as children. Then, if the wrapper component updates its own state, React knows that its children don’t need to re-render.

useTransition

  • useTransition is a React Hook that lets you update the state without blocking the UI. ( If we wrap a function inside startTansition, we tell react that it is low priority ) Other state updates will execute and then the setState inside startTransition will be updated. If not both will be batched together which may block the rendering
  • useTransition does not take any parameters.
  • useTransition returns an array with exactly two items:

  • The isPending flag that tells you whether there is a pending Transition.
  • The startTransition function that lets you mark a state update as a Transition.

useDeferredValue

  • useDeferredValue is a React Hook that lets you defer updating a part of the UI.
  • Showing stale content while fresh content is loading
  • During the initial render, the deferred value will be the same as the value you provided.
  • During updates, the deferred value will “lag behind” the latest value. In particular, React will first re-render without updating the deferred value, and then try to re-render with the newly received value in the background.

Resource hooks

use

use is a React Hook that lets you read the value of a resource like a Promise or context.

import { use } from 'react';

function MessageComponent({ messagePromise }) {
  const message = use(messagePromise);
  const theme = use(ThemeContext);


Unlike useContext, use can be called in conditionals and loops like if

Effect hooks

useEffect

  • You need to pass two arguments to useEffect:
  • A setup function with setup code that connects to that system.
  • It should return a cleanup function with cleanup code that disconnects from that system.
  • A list of dependencies including every value from your component used inside of those functions.
  • React calls your setup and cleanup functions whenever it’s necessary, which may happen multiple times:
  • Your setup code runs when your component is added to the page (mounts).
  • After every re-render of your component where the dependencies have changed:
  • First, your cleanup code runs with the old props and state.
  • Then, your setup code runs with the new props and state.
  • Your cleanup code runs one final time after your component is removed from the page (unmounts).

Caveats

  • If your Effect depends on an object or a function created during rendering, it might run too often. For example, this Effect re-connects after every render because the options object is different for every render:
  • No dependency array: re-runs after every render

Remove unnecessary Effect

  • You don’t need Effects to transform data for rendering
  • You don’t need Effects to handle user events.