context from context provider in layout not available in page?
Unanswered
Giant Chinchilla posted this in #help-forum
Giant ChinchillaOP
I am getting error "Error: (0 , _components_Context_LangContext_LangContextWEBPACK_IMPORTED_MODULE_2.useLangContext) is not a function"
src/app/[lang]/page.tsx:
const {dictionary} = useLangContext();
Is it because both layout and page are server components?
Code below:
src/app/[lang]/page.tsx:
const {dictionary} = useLangContext();
Is it because both layout and page are server components?
Code below:
11 Replies
Giant ChinchillaOP
// LangContext.tsx
"use client";
import React, { useContext } from "react";
import { Locale } from "@root/i18n-config";
import { Dictionary } from "@/types/types";
interface ILangContext {
lang: Locale;
dictionary: Dictionary;
};
export const LangContext = React.createContext<ILangContext | undefined>(undefined);
interface ILangProvider {
lang: Locale;
dictionary: Dictionary;
children?: React.ReactNode;
};
export const LangProvider: React.FC<ILangProvider> = (props) => {
return (
<LangContext.Provider value={{
lang: props.lang,
dictionary: props.dictionary,
}}>{props.children}</LangContext.Provider>
);
};
export const useLangContext = () => {
const context = useContext(LangContext);
if (context === undefined) {
throw new Error("useLangContext must be used within a LangProvider");
}
return context;
};// layout.tsx
import type { Metadata } from "next";
import NextTopLoader from "nextjs-toploader";
import BaseLayout from "@/layouts/BaseLayout/BaseLayout";
import { getDictionary } from "@/get-dictionary";
import { Locale } from "@root/i18n-config";
import { Inter } from "next/font/google";
import "./globals.scss";
import "bootstrap/dist/css/bootstrap.min.css";
import { LangProvider } from "@/components/Context/LangContext/LangContext";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Home",
};
export default async function RootLayout({
params: { lang },
children,
}: Readonly<{
params: { lang: Locale };
children: React.ReactNode;
}>) {
const dictionary = await getDictionary(lang);
return (
<html lang={lang}>
<body className={inter.className}>
<LangProvider lang={lang} dictionary={dictionary}>
<BaseLayout>
{children}
</BaseLayout>
</LangProvider>
</body>
</html>
);
};// src/app/[lang]/page.tsx
import { Locale } from "@root/i18n-config";
import Link from 'next/link';
import { useLangContext } from "@/components/Context/LangContext/LangContext";
export default function IndexPage() {
const {dictionary} = useLangContext(); // ERROR HERE
return (
<div></div>
);
};the same
const {dictionary} = useLangContext(); does work in a client component that is inside <BaseLayout>Giant ChinchillaOP
or does layout not wrap pages?
I have no idea why the context is not available in page, but is available in BaseLayout
Giant ChinchillaOP
do I also need to do
const dictionary = await getDictionary(lang); in page.tsx instead of using the context?because that works
but that kind of defeats the purpose of layout
because i am repeating myself twice
Sun bear
Is the page.tsx a client component? It should be the case if you use "use..." Hooms