自定义React Hook调用updateData后内部state未更新问题求助
问题原因及修复方案
核心问题原因
- 拼写错误导致状态更新逻辑失效:
声明状态时更新函数名拼写错误const [data, setDtata] = React.useState<string | null>(null),多写了一个字母t,后续调用的setData属于未定义方法,自然不会触发状态更新。 - useEffect依赖项配置错误:
useEffect第二个参数要求传入数组类型的依赖列表,当前代码直接传入data变量而非[data],会导致useEffect每次组件渲染都重复执行,不符合“仅当data变化时同步到localStorage”的预期逻辑。 - 自定义Hook状态独立,无法跨组件共享:
React自定义Hook的状态和调用它的组件绑定,每在一个新组件中调用useData()都会生成一套独立的状态和操作方法。你在某个组件调用updateData更新的是当前组件绑定的Hook状态,路由组件中调用useData()生成的是全新的状态实例,初始值就是null,自然拿不到其他组件更新后的值。 - 类型声明错误:
getData函数的返回值类型声明为void,但实际返回了data变量,不符合TS类型约束。
修复方案
如果需要跨组件共享状态,建议用React Context封装这部分逻辑:
import React, { createContext, useContext, useState, useEffect } from 'react'; type UseDataHook = { deleteData: () => void; getData: () => string | null; updateData: (val: string) => void; } const DataContext = createContext<UseDataHook | null>(null); export function DataProvider({ children }: { children: React.ReactNode }) { // 修正setter拼写 const [data, setData] = useState<string | null>(null); // 修正依赖数组格式 useEffect(() => { data ? localStorage.setItem("data-key", data) : localStorage.removeItem("data-key"); }, [data]); function deleteData(): void { setData(null); } // 修正返回类型,优先从localStorage取值避免刷新丢失状态 function getData(): string | null { return data ?? localStorage.getItem("data-key"); } function updateData(newData: string): void { console.log("updating data..."); setData(newData); } return ( <DataContext.Provider value={{ deleteData, getData, updateData }}> {children} </DataContext.Provider> ) } // 封装调用Hook,避免每次都判空 export function useData() { const context = useContext(DataContext); if (!context) throw new Error('useData must be used within DataProvider'); return context; }
之后在应用根组件包裹DataProvider即可:
// App.tsx示例 import { DataProvider } from './useData'; function App() { return ( <DataProvider> {/* 路由、全局组件等所有子内容 */} <Routes /> </DataProvider> ) }
修改完成后所有组件调用useData()拿到的都是全局共享的状态,可正常跨组件读写。
内容的提问来源于stack exchange,提问作者clev
相关产品推荐
相关产品推荐

