Skip to content

Context

Context is a way of sharing state with many child components without having to pass them via props.

tsx
// context/foo.ts
import { createContext, useState } from "react";

const MyContext = createContext();

function Provider({ children }) {
  const [value, setValue] = useState(0);

  const incrementValue = () => {
    setValue(value + 1);
  };

  const valueToShare = {
    value,
    incrementValue,
  };

  return (
    <MyContext.Provider value={valueToShare}>{children}</MyContext.Provider>
  );
}

export { Provider };
export default MyContext;

// In wrapping component...
import { Provider } from "context/foo";

function Parent() {
  return (
    <Provider>
      <Children />
    </Provider>
  );
}

// In consuming component
import { useContext } from "react";
import { MyContext } from "../context/foo";

function Child() {
  const { value, incrementValue } = useContext(MyContext);
}

useCallback

This hook is used to fix some bugs when calling functions stored within contexts from useEffect in a child component. Since useEffect requires the function to be added as a dependency in the second argument, it will rerun that effect whenever that function is called because calling it forces the context to rerender, which in turn creates a new version of that function. So to fix this, we need to use useCallback to create a stable reference to that function.

tsx
// context/foo.ts
import { createContext, useState, useCallback } from "react";

const MyContext = createContext();

function Provider({ children }) {
  const [value, setValue] = useState(0);

  const fetchValue = useCallback(() => {
    newValue = fetch("localhost:8080");
    setValue(newValue);
  }, []);

  const valueToShare = {
    value,
    fetchValue,
  };

  return (
    <MyContext.Provider value={valueToShare}>{children}</MyContext.Provider>
  );
}