首先我们来聊一聊(上下文)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. python 之 文件I/0

    打开和关闭文件 open()函数 必须要open()内置函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写. 语法 file object=open(file_name [,acc ...

  2. delimiters 插值 选项

    delimiters差值选项vue默认是{{}},这个选项可以把这个差值形式进行改变,这里讲,默认插值改成${} html <div id="app"> <div ...

  3. 【译】第11节---数据注解-TimeStamp

    原文:http://www.entityframeworktutorial.net/code-first/TimeStamp-dataannotations-attribute-in-code-fir ...

  4. QT移植无法启动 This application failed to start because it could not find or load the QT platform

    QT配置好在自己机器上可以运行,但在别人机器上一直弹出 "This application failed to start because it could not find or load ...

  5. _itemmod_unbind

    该表中的物品可以用一定代价进行解绑,解绑后可以移动,但下线将会导致物品重新绑定 `entry`物品entry `reqId` 解绑消耗模板Id `备注` 备注

  6. unity shader base pass and additional pass

      [Unity Shaders]Shader中的光照,shadersshader 写在前面 自己写过Vertex & Fragment Shader的童鞋,大概都会对Unity的光照痛恨不已 ...

  7. 【bzoj】4538: [Hnoi2016]网络

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4538 维护一个数据结构支持对于一颗树的操作,需要支持: 1.对于树上的一条路径上的每个点上 ...

  8. sqlserver 中常见的函数 数学函数

    create table testnum( ID int identity(1,1), num float) insert testnum values (1) insert testnum valu ...

  9. 力扣(LeetCode)922. 按奇偶排序数组 II

    给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数. 对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数:当 A[i] 为偶数时, i 也是偶数. 你可以返回任何满足上述条件的数组 ...

  10. Java面试宝典(说说&和&&的区别)

    &和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false. ...