首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >提供一些使用Context+useContext进行跨层级组件通信的具体示例

提供一些使用Context+useContext进行跨层级组件通信的具体示例

原创
作者头像
小焱
发布2025-08-26 17:15:37
发布2025-08-26 17:15:37
2470
举报
文章被收录于专栏:前端开发前端开发

下面提供几个使用 Context + useContext 进行跨层级组件通信的具体示例,覆盖常见场景如主题切换、用户信息共享、权限控制等,帮助理解其实际应用:

示例1:主题切换(全局样式共享)

实现跨层级组件共享主题配置(如颜色、字体),支持动态切换主题。

代码语言:jsx
复制
// 1. 创建主题Context
import { createContext, useContext, useState } from 'react';

// 创建Context时可设置默认值(非必填)
const ThemeContext = createContext({
  theme: 'light',
  toggleTheme: () => {}
});

// 2. 提供主题数据的顶层组件(Provider)
export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  // 切换主题的方法
  const toggleTheme = () => {
    setTheme(prev => prev === 'light' ? 'dark' : 'light');
  };

  // 提供给后代组件的数据(包含状态和方法)
  const value = { theme, toggleTheme };

  return (
    <ThemeContext.Provider value={value}>
      {children} {/* 后代组件会包裹在这里 */}
    </ThemeContext.Provider>
  );
}

// 3. 自定义Hook简化使用(可选,推荐)
export function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme must be used within a ThemeProvider');
  }
  return context;
}

// 4. 深层子组件使用(跨层级获取)
function ThemedButton() {
  // 直接获取主题配置,无需通过props传递
  const { theme, toggleTheme } = useTheme();

  return (
    <button 
      style={{
        background: theme === 'light' ? '#fff' : '#333',
        color: theme === 'light' ? '#333' : '#fff',
        padding: '8px 16px',
        border: '1px solid #ccc'
      }}
      onClick={toggleTheme}
    >
      当前主题:{theme}(点击切换)
    </button>
  );
}

// 5. 组件嵌套关系(跨3层)
function App() {
  return (
    <ThemeProvider>
      <div>
        <h1>主题示例</h1>
        <ParentComponent />
      </div>
    </ThemeProvider>
  );
}

function ParentComponent() {
  return <ChildComponent />; // 中间层无需处理主题数据
}

function ChildComponent() {
  return <ThemedButton />; // 深层组件直接使用
}

关键点

  • 通过 ThemeProvider 包裹整个应用,所有后代组件可获取主题数据
  • 自定义 useTheme Hook 封装 useContext,并添加错误处理(避免在 Provider 外使用)
  • 支持传递方法(如 toggleTheme),实现跨层级交互

示例2:用户信息共享(全局状态)

在多层级组件中共享用户登录状态、个人信息等全局数据。

代码语言:jsx
复制
// 1. 创建用户Context
import { createContext, useContext, useState } from 'react';

const UserContext = createContext(null);

// 2. 用户Provider
export function UserProvider({ children }) {
  const [user, setUser] = useState({
    name: '游客',
    isLogin: false
  });

  // 登录/退出方法
  const login = (username) => {
    setUser({ name: username, isLogin: true });
  };

  const logout = () => {
    setUser({ name: '游客', isLogin: false });
  };

  return (
    <UserContext.Provider value={{ user, login, logout }}>
      {children}
    </UserContext.Provider>
  );
}

// 3. 自定义Hook
export function useUser() {
  const context = useContext(UserContext);
  if (!context) {
    throw new Error('useUser must be used within a UserProvider');
  }
  return context;
}

// 4. 深层组件使用(如导航栏、个人中心)
function Navbar() {
  const { user, logout } = useUser();
  return (
    <nav style={{ padding: '10px', background: '#f0f0f0' }}>
      <span>欢迎,{user.name}</span>
      {user.isLogin ? (
        <button onClick={logout} style={{ marginLeft: '10px' }}>
          退出
        </button>
      ) : null}
    </nav>
  );
}

function LoginButton() {
  const { user, login } = useUser();
  if (user.isLogin) return null;
  return (
    <button onClick={() => login('张三')}>
      登录
    </button>
  );
}

// 5. 组件层级(跨4层)
function App() {
  return (
    <UserProvider>
      <Navbar />
      <Content />
    </UserProvider>
  );
}

function Content() {
  return <ProfileSection />;
}

function ProfileSection() {
  return <LoginButton />;
}

关键点

  • 全局共享用户状态,避免在每个组件中重复定义登录逻辑
  • 深层组件(如 NavbarLoginButton)可直接读写用户信息,无需中间层传递
  • 适合用户信息、权限等全局共享的数据

示例3:多Context组合(复杂场景)

当需要共享多种独立数据(如主题 + 用户)时,可组合多个 Context。

代码语言:jsx
复制
// 组合示例:同时使用ThemeContext和UserContext
function App() {
  // 多层Provider嵌套,分别提供不同数据
  return (
    <ThemeProvider>
      <UserProvider>
        <Layout />
      </UserProvider>
    </ThemeProvider>
  );
}

function Layout() {
  return <DeepComponent />;
}

function DeepComponent() {
  // 同时使用两个Context的数据
  const { theme } = useTheme();
  const { user } = useUser();

  return (
    <div style={{ background: theme === 'dark' ? '#333' : '#fff' }}>
      <p>用户:{user.name}</p>
      <p>主题:{theme}</p>
    </div>
  );
}

关键点

  • 多个 Context 可独立维护,避免单一 Context 数据过于臃肿
  • 后代组件可按需获取不同 Context 的数据

使用注意事项

  1. 避免过度使用:Context 会导致所有消费它的组件在数据变化时重新渲染,频繁更新的数据(如表单输入)不适合用 Context
  2. 拆分 Context:将频繁变化的数据和稳定数据拆分为不同 Context(如主题和用户信息分开)
  3. 默认值陷阱createContext 的默认值仅在组件未被 Provider 包裹时生效,而非"初始值",需注意判断
  4. 性能优化
    • 对复杂对象使用 useMemo 缓存,避免不必要的重渲染:
代码语言:jsx
复制
// 在Provider中优化
const value = useMemo(() => ({ theme, toggleTheme }), [theme]);

这些示例覆盖了 Context + useContext 的核心用法,实际开发中可根据需求扩展(如添加权限控制、多语言切换等),是 React 中跨层级通信的高效方案。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 示例1:主题切换(全局样式共享)
  • 示例2:用户信息共享(全局状态)
  • 示例3:多Context组合(复杂场景)
  • 使用注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档