const Ctx = createContext(默认值),生产者用"> const Ctx = createContext(默认值),生产者用"> const Ctx = createContext(默认值),生产者用">
React 词条目录
前端Wiki/React/深入/组件通信与 Context

Context 跨层通信

Context 让数据“跨层直送”:创建 const Ctx = createContext(默认值),生产者用 <Ctx.Provider value={数据}> 包住组件树,任意深处的后代用 useContext(Ctx) 直接拿到数据,沿途组件不需要过路传递。

适用场景是“全局且低频变化”:主题色、用户登录态、语言、路由。而不适合做全局状态管理:Context 的 value 一变,所有消费组件全部重渲染——高频更新(计数器、列表数据、表单输入)用它会很卡,这类请走状态库。

  • createContext + Provider下发 + useContext 任意层读取
  • 适合全局低频数据:主题、用户态、语言、权限
  • value 一变所有消费者整体重渲染:高频数据别用 Context
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Context</title>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const { useState, useContext, createContext } = React;

// 1. 创建 Context(带默认值:无人 Provider 时用它)
const ThemeCtx = createContext({ color: '#087ea4', name: '默认主题' });

// 最深层组件:一行 useContext 直取,不经中间组件
function Leaf() {
  const theme = useContext(ThemeCtx);
  return <p style={{ color: theme.color }}>深层组件:{theme.name}</p>;
}

function Middle() {
  return <div>中间层(不需要传 props)<Leaf /></div>;
}

function App() {
  const [dark, setDark] = useState(false);
  const theme = dark
    ? { color: '#90cdf4', name: '夜间主题' }
    : { color: '#087ea4', name: '日间主题' };
  return (
    // 2. Provider 提供数据
    <ThemeCtx.Provider value={theme}>
      <div style={{ padding: 16 }}>
        <button onClick={() => setDark(d => !d)}>切换主题</button>
        <Middle />
      </div>
    </ThemeCtx.Provider>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
本节要点Context 解决 prop drilling:Provider 发、useContext 收;只适合全局低频数据。