首先我们来聊一聊(上下文)Context。

上下文(Context) 提供了一种通过组件树传递数据的方法,无需在每个级别手动传递 props 属性。

在典型的 React 应用程序中,数据通过 props 自上而下(父到子)传递,但对于应用程序中许多组件所需的某些类型的 props(例如环境偏好,UI主题),这可能很麻烦。 上下文(Context) 提供了在组件之间共享这些值的方法,而不必在树的每个层级显式传递一个 prop 。

1.何时使用Context

Context 旨在共享一个组件树内可被视为 “全局” 的数据,例如当前经过身份验证的用户,主题或首选语言等。

API:

  React.createContext:创建一个 { Provider, Consumer } 对。当 React 渲染 context Consumer 时,它将从组件树中匹配最接近的 Provider 中读取当前的 context 值。

const {Provider, Consumer} = React.createContext(defaultValue);

  Provider:React组件允许 Consumer(使用者) 订阅 context 的改变。 一个 Provider 可以连接到许多 Consumers 。

<Provider value={/* some value */}>

  Consumer:一个可以订阅 context 变化的 React 组件。需要接收一个 函数作为子节点。 该函数接收当前 context 值并返回一个 React 节点

<Consumer>
{value => /* render something based on the context value */}
</Consumer>

只要 Provider 的 value 属性发生变化是,所有属于该 Provider 后代的 Consumers 就会重新渲染。 从 Provider 到它的后代 Consumers 的传播不受 shouldComponentUpdate 方法的约束, 所以即使当祖先组件退出更新时,后代 Consumer 也会被更新。

例如,

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

class App extends React.Component {
render() {
//
return (
<ThemeContext.Provider value="dark">
      <Toolbar />
</ThemeContext.Provider>
);
}
} function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
} function ThemedButton(props) {
//
return (
<ThemeContext.Consumer>
    {theme => <Button {...props} theme={theme} />}
</ThemeContext.Consumer>
);
}

当一些数据需要在不同的嵌套级别上被许多组件访问时,首先考虑使用 Context 。 请谨慎使用它,因为它使组件重用更加困难。

如果你只想避免在多个级别上传递一些 props ,那么 组件组合 通常比 Context 更简单。

2.在生命周期中访问Context

不是将 context 添加到每个生命周期方法中, 你只需将它作为 props , 然后像使用 props 一样使用它即可。

例如,

class Button extends React.Component {
componentDidMount() {
// ThemeContext的值为this.props.theme
} componentDidUpdate(prevProps, prevState) {
// 之前的ThemeContext的值为prevProps.theme
// 新的ThemeContext的值为this.props.theme
} render() {
const {theme, children} = this.props;
return (
<button className={theme || 'light'}>
{children}
</button>
);
}
} export default props => (
<ThemeContext.Consumer>
{theme => <Button {...props} theme={theme} />}
</ThemeContext.Consumer>
);

3.高阶组件中的Context

如果我们想在很多的地方使用ThemContetx,可以创建一个高阶组件在其中使用,如,

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

// 这个方法接收一个component
export function withTheme(Component) {
// 然后返回另一个component
return function ThemedComponent(props) {
// 并且渲染一个包含context theme的包装组件
return (
<ThemeContext.Consumer>
{theme => <Component {...props} theme={theme} />}
</ThemeContext.Consumer>
);
};
}

那么现在,任何依赖于theme context的组件都可以使用创建的withTheme函数轻松订阅它,

function Button({theme, ...rest}) {
return <button className={theme} {...rest} />;
} const ThemedButton = withTheme(Button);

4.转发 Refs 给 context Consumer(使用者)

渲染 prop(属性) API的一个问题是 refs 不会自动传递给封装元素。 为了解决这个问题,使用 React.forwardRef

/*fancy-button.js*/
class FancyButton extends React.Component {
focus() {
// ...
}
// ...
} // 使用context传递当前的theme给FancyButton.
// 使用forwardRef更好的传递refs给FancyButton
export default React.forwardRef((props, ref) => (
<ThemeContext.Consumer>
{theme => (
<FancyButton {...props} theme={theme} ref={ref} />
)}
</ThemeContext.Consumer>
));
/*app.js*/
import FancyButton from './fancy-button'; const ref = React.createRef(); // 我们的ref将指向FancyButton组件,
// 并且没有ThemeContext.Consumer包裹它.
// 这意味着我们可以在FancyButton上应用方法,就像ref.current.focus()这样
<FancyButton ref={ref} onClick={handleClick}>
Click me!
</FancyButton>;

关于react16.4——上下文Context的更多相关文章

  1. 编程中经常看到上下文context,这个上下文指得是什么?

    举个栗子:小美气呼呼对我说:“你去死吧”,我当时哭了. 场景1:小美刚转学到我们学校,我暗恋了她很久,有一天鼓足勇气,向她表白,小美气呼呼对我说:“你去死吧”,我当时就哭了.场景2我跟小美从小青梅竹马 ...

  2. Android上下文Context

    Android上下文Context介绍 在应用开发中最熟悉而陌生的朋友-----Context类 ,说它熟悉,是应为我们在开发中时刻的在与它打交道,例如:Service.BroadcastReceiv ...

  3. 01 . Go之从零实现Web框架(框架雏形, 上下文Context,路由)

    设计一个框架 大部分时候,我们需要实现一个 Web 应用,第一反应是应该使用哪个框架.不同的框架设计理念和提供的功能有很大的差别.比如 Python 语言的 django和flask,前者大而全,后者 ...

  4. Javascript的“上下文”(context)

    一:JavaScript中的“上下文“指的是什么 百科中这样定义: 上下文是从英文context翻译过来,指的是一种环境. 在软件工程中,上下文是一种属性的有序序列,它们为驻留在环境内的对象定义环境. ...

  5. 前后台获取上下文context

    1.web server端获取上下文:Context ctx = WafContext.getInstance().getContext();上下文中包含当前登录组织.当前登录用户.语种.数据库.客户 ...

  6. MVC学习笔记---各种上下文context

    0  前言 AspNet MVC中比较重要的上下文,有如下: 核心的上下文有HttpContext(请求上下文),ControllerContext(控制器上下文) 过滤器有关有五个的上下文Actio ...

  7. spring3.0的BeanFactory上下文context获取不到bean

    开门见山,背景: 系统初始化的时候扫包实例化bean,然后一个工具类实现ServletContextAware接口,拿到servletContext之后: WebApplicationContextU ...

  8. linux内核--几个上下文(context)

    为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行,这种行为叫进程切换(process switch),任务切换(task switch)或上下文切换(con ...

  9. 上下文Context详细介绍

    1.先看看它的继承结构,下图可以看出Context首先是一个抽象类,继承了Object,Activity,Service,Application都继承了它 2.API中对它的描述: @1Context ...

随机推荐

  1. P2257 YY的GCD(莫比乌斯反演)

    第一次做莫比乌斯反演,推式子真是快乐的很啊(棒读) 前置 若函数\(F(n)\)和\(f(d)\)存在以下关系 \[ F(n)=\sum_{n|d}f(d) \] 则可以推出 \[ f(n)=\sum ...

  2. Linux(CentOS)上面搭建Nginx环境

    总体上来说,Linux 这个系统其实挺好用的 除了看不见界面,但是用起来确实是比Window好用太多了,不废话了,直接说搭建环境的步骤! 安装Nginx 编译运行时的环境 参考博客:http://ww ...

  3. Shiro学习笔记四(Shiro集成WEB)

    这两天由于家里出了点事情,没有准时的进行学习.今天补上之前的笔记 -----没有学不会的技术,只有不停找借口的人 学习到的知识点: 1.Shiro 集成WEB 2.基于角色的权限控制 3.基于权限的控 ...

  4. CIFAR-10与ImageNet图像识别

    2.1.2 下载CIFAR-10 数据 python cifar10_download.py # Copyright 2015 The TensorFlow Authors. All Rights R ...

  5. Linux命令1——a

    addUser: -c:备注 -d:登陆目录 -e:有效期限 -f:缓冲天数 -g:组 -b:用户目录 -G:附加组 -s:制定使用默认的shell -u:指定用户ID -r:建立系统账号 -M:不自 ...

  6. VHDL 例程

    以下程序未经仿真,仅供说明 语法 声明参考库ieee,使用ieee中的std_logic_1164包全部条目可见 library ieee; use ieee.std_logic_1164.all; ...

  7. 1、My Scripts

    1.写一个包含命令.变量和流程控制的语句来清除/var/log的messages日志文件的shell脚本.(P26)(11-21) 2.利用$0和(dirname.basename)取出当前路径的目录 ...

  8. 在ETH交易区块链里查看北大的那封信

    本文仅限于科普编码知识使用,随便举的例子不代表本人立场. 欢迎在其他网站传播,但转载不得标注来源及作者. 1.随便打开一个ETH区块链浏览网站,比如:https://www.etherchain.or ...

  9. 再谈java编码

    一篇好文:从原理上搞懂编码——究竟什么是编码?什么是解码?什么是字节流? encode,即把字符按照指定的<编码gbk utf-8等>编码成该<编码>所表示的字节 decode ...

  10. SQL中 根据行号设置每行数据的排序数值

    根据行号自动把当前行号插入到某列中 实现排序 update tempTable set DisplayOrder = right( CAST(rownum as NVARCHAR),5) from(  ...