【Day 21】Hook 04:useContext

useContext

useContext 本质上是 Context 的语法糖,
精简了 Context 取得值的方式。


使用方法

useContext 会接收一个
「Context Object」作为参数
也就是 React.createContext() 的回传值,
并回传该 Context 目前的值。

// ThemeContext.js
const ThemeContext = React.createContext();

// MyComponent.js
const value = useContext(ThemeContext);

Context 目前的值则取决於上层 component
距离最近<ThemeContext.Provider>value prop。

const App = () => {
    const [dark, setDark] = useState(true);
    
    return (
        <>
            <ThemeContext.Provider value={dark}>
              <MyComponent />
            </ThemeContext.Provider>
        </>
    );
}

当 component 上层最近的
<ThemeContext.Provider> 更新时,
useContext 会触发重新 render,
并取得最新传递到 ThemeContext 里的 value

// MyComponent.js
import { ThemeContext } from './App.js';

const ButtonGroupComponent = () => {
  const darkTheme = useContext(ThemeContext)
  
  const themeStyle = {
    backgroundColor: darkTheme ? '#2c3e50': '#f1c40f',
    color: darkTheme ? '#ecf0f1' : '#2c3e50'
  }
  
  return (
    <button style={themeStyle}>useContext</button>
  );
} 

useContext(ThemeContext) 等同於 class 中的 static contextType = ThemeContext<ThemeContext.Consumer>


完整使用范例


const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

总结

useContext 只能让你读取 context 及订阅其变更,
component tree 的上层仍然需要
使用 <ThemeContext.Provider> 来提供 context 的值。

但 useContext 可以让你免去使用 Consumer
包覆要接受资料的子元件,
而是将 ThemeContext 里面的资料直接赋予给变数,
在存取时更加直观方便。


参考资料


<<:  Day22 - 错误捕捉、全域 CSS、共用 Layout,就用 _app.tsx 来搞定吧!

>>:  应用系统的防护基准-传输与资料的加密与保护

(29) 试着学 Hexo - 奇淫技巧 - 快速上传你的图片到 imgur

前言 接下来来讲讲如何透过 VSCode 快速上传图片到 imgur 吧! imgur 前面章节「(...

Day1-当水手也得知船长怎样 什麽是k8s

当水手也得知船长怎样 什麽是k8s TL DR 经过这三十天 阅读完的人可以得到以下技能(希望能) ...

Thunkable学习笔记 8 - Data Viewer List 想做资产盘点(一)

Thunkable能做资产盘点吗? 也不确定能否成功, 边做边想边调整, 准备资料先 搬出barco...

Day [2] — this:作用域 — JS之浸猪笼系列

如果你不知道这个系列为什麽叫这种激烈的名字可以看这篇: Day [0] — JS之浸猪笼系列 如果你...

[Day 27] 资料产品开发实务 - 加工资料 - ETL 开发流程

介绍一下一般开发 ETL 的流程。每只 ETL 都可以看作是独立的程序,有独立的开发流程。但是不同...