Next.js React TS项目中Context API的setUpOrgId函数未调用问题
问题原因与解决方案
核心问题
你的RootLayout组件并未被UserContextProvider包裹,导致在RootLayout中通过useContext(UserContext)获取到的是Context的默认值(即创建Context时定义的setUpOrgId: (id:number)=> { console.log("init")}),而非Provider中实际提供的handleSetUpId函数。这就是点击按钮时未触发预期日志、orgId无法更新的根本原因。
修复步骤
1. 修正RootLayout结构
将UserContextProvider包裹在RootLayout的内部内容外层,确保RootLayout及其所有子组件都能访问到Provider提供的Context值:
"use client" import { Inter } from "next/font/google"; import "./globals.css"; import UserContextProvider, {UserContext} from "@/app/store/userContext"; import {useContext} from "react"; export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { const {storedOrgId, setUpOrgId} = useContext(UserContext) const updateOrgId = () => { const newOrgId: number = 7 console.log("Layout - update org id called with org id:", newOrgId) setUpOrgId(newOrgId); }; return ( <html lang="en"> <body> {/* 用UserContextProvider包裹内部所有内容 */} <UserContextProvider> <button onClick={updateOrgId}> Click me</button> {children} </UserContextProvider> </body> </html> ); }
2. 添加localStorage持久化逻辑
按照需求将orgId持久化到本地存储,确保页面刷新后值不会丢失。修改UserContextProvider代码:
"use client" import {createContext, ReactNode, useState, useEffect} from 'react'; export const UserContext = createContext({ storedOrgId: 0, setUpOrgId: (id:number)=> { console.log("init")}, }) interface UserContextProviderProps { children: ReactNode; } export default function UserContextProvider({children}:UserContextProviderProps){ // 初始化时从localStorage读取值,无值则用0 const [orgId, setOrgId] = useState(() => { const savedOrgId = localStorage.getItem('orgId'); return savedOrgId ? parseInt(savedOrgId, 10) : 0; }); console.log("userContext current orgId:", orgId) // orgId变化时同步保存到localStorage useEffect(() => { localStorage.setItem('orgId', orgId.toString()); }, [orgId]); const handleSetUpId = (id: number) => { console.log("userContext->setUpId", id) setOrgId(id); } const ctxValue = { storedOrgId: orgId, setUpOrgId: handleSetUpId }; return <UserContext.Provider value={ctxValue}> {children} </UserContext.Provider> }
验证效果
- 点击按钮后,控制台会打印
Layout - update org id called with org id: 7和userContext->setUpId 7,说明函数已正确调用。 - 刷新页面后,orgId会保持为7而非回到0,验证持久化逻辑生效。
内容的提问来源于stack exchange,提问作者MillturnK
相关产品推荐
相关产品推荐

