React 创建 Context

创建

复制代码
创建一个 React Context,用来把"图表预览(或相关共享数据/方法)"放到组件树顶层,
任何子组件都能读取或修改

解决了 "prop drilling"(属性钻取)问题,即:避免将 props 通过多层组件传递

代码编写

js 复制代码
'use client'
import React, { ReactNode, useMemo, useState } from 'react';
import { createContext, useContextSelector, useContext } from 'use-context-selector';

type PreviewData = {
  chartId?: string;
  zoom?: number;
  // ...其他字段
};

type ChartPreviewContextType = {
  preview: PreviewData | null;
  setPreview: (p: PreviewData | null) => void;
};

const ChartPreviewContext = createContext<ChartPreviewContextType | undefined>(undefined);

export const ChartPreviewProvider = ({ children }: { children: ReactNode }) => {
  const [preview, setPreview] = useState<PreviewData | null>(null);

  // useMemo 保证 value 引用稳定,避免无谓重渲染
  const value = useMemo(() => ({ preview, setPreview }), [preview, setPreview]);

  return (
    <ChartPreviewContext.Provider value={value}>
      {children}
    </ChartPreviewContext.Provider>
  );
};

// 简单 hook(如果只需要整个对象)
export const useChartPreviewContext = () => {
  const ctx = useContext(ChartPreviewContext);
  if (!ctx) throw new Error('useChartPreviewContext must be used within ChartPreviewProvider');
  return ctx;
};

// 更细粒度的 selector 用法(推荐:减少重渲染)
// 例如在消费组件中,只订阅 preview 字段:
export const usePreviewData = () => {
  const preview = useContextSelector(ChartPreviewContext, v => v?.preview ?? null);
  return preview;
};

在任意组件中包裹(通常是最顶级的组件,比如Layout 组件)

js 复制代码
<ChartPreviewProvider>
   {children} // 下面的所有组件都可以使用  useChartPreviewContext  来拿到preview 和 setPreview  如果需要其他 请自行添加
 </ChartPreviewProvider> 

注意事项

复制代码
Context 是 React 中非常强大的特性,但需要谨慎使用。
在适当的场景下使用 Context 可以大大简化代码结构,提高开发效率。
但过度使用可能会导致组件复用性降低和性能问题。
相关推荐
天外飞雨道沧桑4 小时前
TypeScript 中 omit 和 record 用法
前端·javascript·typescript
给钱,谢谢!5 小时前
React + PixiJS 实现果园成长页:从状态机到浇水动画
前端·react.js·前端框架
暗冰ཏོ6 小时前
VUE面试题大全
前端·javascript·vue.js·面试
豹哥学前端9 小时前
事件循环(Event Loop)深度解析:让你彻底搞懂 JS 的执行顺序
前端·javascript·面试
竹林8189 小时前
用 wagmi v2 + Next.js 14 搞 NFT 交易市场前端:从合约调用失败到顺利上架,我踩了哪些坑
javascript·next.js
前端不开发10 小时前
用一个 Bookmarklet(书签脚本),给任意网页挂一个可拖拽悬浮窗
前端·javascript
接着奏乐接着舞10 小时前
【无标题】
开发语言·前端·javascript
雨雨雨雨雨别下啦10 小时前
心理健康AI助手 - 项目总结
前端·javascript·vue.js·人工智能·信息可视化
风之舞_yjf10 小时前
Vue基础(32)_TodoList案例
前端·javascript·vue.js
Amos_Web12 小时前
Rspack 源码解析 (2) —— 从 rspack build 到输出 dist,完整编译链路详解
前端·javascript