typescriptreact-contextsolid-js

useContext returns undefined even though it is nested in the provider


I am trying to avoid prop drilling in my Solid application, but contexts all return undefined or my check throws an error.

Error message

SettingsContext.tsx

import {
  createContext,
  useContext,
  createSignal,
  type JSX,
  Accessor,
  Setter,
} from "solid-js";

export const SettingsContext = createContext<SettingsContextType>();

export const SettingsContextProvider = ({
  children,
}: {
  children: JSX.Element | JSX.Element[];
}) => {
  const [settings, setSettings] = createSignal<Settings>({
    ...
  });
  const [isPlaying, setIsPlaying] = createSignal(false);
  const [state, setState] = createSignal("setup");
  const [text, setText] = createSignal(
    ``,
  );

  return (
    <SettingsContext.Provider
      value={{
        settings,
        setSettings,
        isPlaying,
        setIsPlaying,
        state,
        setState,
        text,
        setText,
      }}
    >
      {children}
    </SettingsContext.Provider>
  );
};

export const useSettings = () => {
  const context = useContext(SettingsContext);
  if (!context) {
    throw new Error("useSettings must be used within a SettingsProvider");
  }
  return context;
}

I did also try just using `useContent(SettingsContext)˙ directly.

App.tsx

import {
  SettingsContextProvider,
} from "./contexts/SettingsContext";
import AppContent from "./components/AppContent";

export default function App() {
  return (
    <SettingsContextProvider>
      <AppContent />
    </SettingsContextProvider>
  );
}

I seperated the App.tsx, as I attempt to fix it. I used it in index.tsx too.

AppContent.tsx

import { useSettings } from "../contexts/SettingsContext";

export default function AppContent() {
  const { state, setState } = useSettings();
}

Solution

  • That is because of the prop destructuring which changes the execution order, making the enclosed children run before the parent, not receiving the context value on time.

    You can see this answer for a detailed explanation: https://stackoverflow.com/a/76995880/7134134