
InfoProvider.tsx
import {createContext, useContext} from 'react';
import {InfoType} from '@/types/info';
// 创建info上下文。
const infoContext = createContext<InfoType | null>(null)
// 返回组件中要获取上下文内容,的方法。
export function useInfo() {
const context = useContext(infoContext);
if(!context){
throw new Error('useInfo must be used wintin InfoProvider');
}
}
// 默认返回在外层注入上下文的方法
export function InfoProvider({children}:{children: ReactNode}) {
// 在这里定义一些上下文内容.
// A. 状态:定义要在全局共享的数据(比如用户信息、列表数据)
const [info, setInfo] = useState<InfoData | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
// B. 方法:更新数据的方法(使用 useCallback 确保函数地址不变,优化性能)
const updateInfo = useCallback((newData: InfoData) => {
setInfo(newData);
}, []);
// C. 方法:模拟异步获取数据(比如调 API)
const fetchInfo = useCallback(async (id: string) => {
setIsLoading(true);
try {
// 正常应用中这里会写:const res = await api.getInfo(id);
// setInfo(res.data);
console.log(`正在获取 ID 为 ${id} 的数据...`);
} finally {
setIsLoading(false);
}
}, []);
// D. 方法:重置状态
const resetInfo = useCallback(() => {
setInfo(null);
}, []);
// E. 打包:使用 useMemo 把上述状态和方法打包成一个对象
// 只有依赖项变化时,这个对象的引用才会变。这是为了防止所有子组件无效重渲染。
const contextValue = useMemo(() => ({
info,
isLoading,
updateInfo,
fetchInfo,
resetInfo
}), [info, isLoading, updateInfo, fetchInfo, resetInfo]);
return (
<infoContext.Provider value={contextValue}>
{children}
</infoContext.Provider>
);
}
export default InfoProvider;原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。