context

定义: Context提供了一种方式,能够让数据在组件树中传递,而不必一级一级手动传递。

API : createContext(defaultValue?)。

使用方法:

首先要引入createContext

import React, { Component, createContext } from 'react';

然后创建一个Context

const BatteryContext = createContext();

然后用BatteryContext.Provider包裹组件并且传递属性值。

<BatteryContext.Provider value={60}>
<Middle />  //子组件
</BatteryContext.Provider>

为了方便看出效果,将定义一个子组件和一个孙组件。然后不通过子组件,孙组件直接取值。

import React, { Component, createContext } from 'react';

const BatteryContext = createContext();

//声明一个孙组件
class Leaf extends Component {
render() {
return ( )
}
} //声明一个子组件
class Middle extends Component {
render() {
return <Leaf />
}
} class App extends Component {
render(){
return (
<BatteryContext.Provider value={60}>
<Middle />
</BatteryContext.Provider>
);
}
} export default App;

孙组件需要BatteryContext.Consumer来接收值,Consumer里面不能直接渲染其他组件,而是要声明一个函数。函数的参数就是context的值。

class Leaf extends Component {
render() {
return (
<BatteryContext.Consumer>
{
battery => <h1>Battery : {battery}</h1>
}
</BatteryContext.Consumer>
)
}
}

效果图;

这样没通过Middle组件来传递值,但是Leaf组件能通过context来获得属性。这就是context的基本用法。

context不但能跨层级来传递属性值,还能在属性值发生变化的时候重渲染Consumer下面的元素,举个例子:
 
在state中定义battery并赋值
state = {
battery: 60
}
然后做一个按钮,每次点击的时候都要battery减一。  代码:
render() {
const { battery } = this.state;
return (
<BatteryContext.Provider value={battery}>
<button
type="button"
onClick={() => this.setState({ battery: battery - 1 })}
>
减减
</button>
<Middle />
</BatteryContext.Provider>
);
}
全部代码:
import React, { Component, createContext } from 'react';

const BatteryContext = createContext();

//声明一个孙组件
class Leaf extends Component {
render() {
return (
<BatteryContext.Consumer>
{
battery => <h1>Battery : {battery}</h1>
}
</BatteryContext.Consumer>
)
}
} //声明一个子组件
class Middle extends Component {
render() {
return <Leaf />
}
} class App extends Component {
state = {
battery: 60
}
render() {
const { battery } = this.state;
return (
<BatteryContext.Provider value={battery}>
<button
type="button"
onClick={() => this.setState({ battery: battery - 1 })}
>
减减
</button>
<Middle />
</BatteryContext.Provider>
);
} } export default App;

效果图:

这样每次点击都会使battery得数值发生变化,从而重渲染Consumer下面的元素。

如果有多个Context该怎么做呢?我们在创建一个 Context
const OnLineContext = createContext();
如果有多个context变量的话,只需要把Privider嵌套进来即可,顺序不重要。接下来声明online的Provider了。
class App extends Component {
state = {
battery: 60,
online: false
}
render() {
const { battery, online } = this.state;
return (
<BatteryContext.Provider value={battery}>
<OnLineContext.Provider value={online} >
<button
type="button"
onClick={() => this.setState({ battery: battery - 1 })}
>
减减
</button>
<button
type="button"
onClick={() => this.setState({ online: !online })}
>
Switch
</button>
<Middle />
</OnLineContext.Provider>
</BatteryContext.Provider>
);
}
与Provider类似。Consumer也需要嵌套,顺序不重要。只要Consumer需要声明函数,所以要注意语法。
class Leaf extends Component {
render() {
return (
<BatteryContext.Consumer>
{
battery => (
<OnLineContext.Consumer>
{
online => <h1>Battery : {battery} , Online : {online.toString()}</h1>
}
</OnLineContext.Consumer>
)
}
</BatteryContext.Consumer>
)
}
}

全部代码:

import React, { Component, createContext } from 'react';

const BatteryContext = createContext();
const OnLineContext = createContext(); //声明一个孙组件
class Leaf extends Component {
render() {
return (
//与Provider类似。Consumer也需要嵌套,顺序不重要。只要Consumer需要声明函数,所以要注意语法。
<BatteryContext.Consumer>
{
battery => (
<OnLineContext.Consumer>
{
online => <h1>Battery : {battery} , Online : {online.toString()}</h1>
}
</OnLineContext.Consumer>
)
}
</BatteryContext.Consumer>
)
}
} //声明一个子组件
class Middle extends Component {
render() {
return <Leaf />
}
} class App extends Component {
state = {
battery: 60,
online: false
}
render() {
const { battery, online } = this.state;
//接下来声明online的Provider了。如果有多个context变量的话,只需要把Privider嵌套进来即可,顺序不重要。
return (
<BatteryContext.Provider value={battery}>
<OnLineContext.Provider value={online} >
<button
type="button"
onClick={() => this.setState({ battery: battery - 1 })}
>
减减
</button>
<button
type="button"
onClick={() => this.setState({ online: !online })}
>
Switch
</button>
<Middle />
</OnLineContext.Provider>
</BatteryContext.Provider>
);
} } export default App;

效果图:

还有一个问题 , 如果Consumer向上找不到对应的Provider怎么办?
 
其实即使找不到也不会报错,而是显示为空。那怎么设置默认值呢?
 
那上面的demo举例 ,刚才我们设置的battery为60。如果Consumer向上找不到BatteryContext.Provider的值,我们可以这样设置默认值:
const BatteryContext = createContext(30);
这样BatteryContext.Consumer向上找不到值,就会取默认值30。
context不仅仅只是可以传数值,也可以传函数。大家可以试试看。
最后再提示一下大家,不要滥用context,不然会影响组件的独立性。 如果一个组件中只使用一个Context的话,就可以使用contextType代替Consumer。详见https://www.cnblogs.com/littleSpill/p/11221817.html
 
 
 

React的Context的使用方法简介的更多相关文章

  1. React的contextType的使用方法简介

    上一篇介绍了Context的使用方法.但是Context会让组件变得不纯粹,因为依赖了全局变量.所以这决定了Context一般不会大规模的使用.所以一般在一个组件中使用一个Context就好. 由于C ...

  2. iOS中常用的四种数据持久化方法简介

    iOS中常用的四种数据持久化方法简介 iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 ...

  3. 手写一个React-Redux,玩转React的Context API

    上一篇文章我们手写了一个Redux,但是单纯的Redux只是一个状态机,是没有UI呈现的,所以一般我们使用的时候都会配合一个UI库,比如在React中使用Redux就会用到React-Redux这个库 ...

  4. 网络神器Greasemonkey(油猴子)使用方法简介+脚本分享【转载】

    推荐下,觉得这个方法有用, 今天艾薇百科来介绍一下功能强大的Greasemonkey,俗称"油猴子",Greasemonkey可以自由定制网页,实现你想要的各种功能.堪称" ...

  5. Redis Cluster搭建方法简介22211111

    Redis Cluster搭建方法简介 (2013-05-29 17:08:57) 转载▼       Redis Cluster即Redis的分布式版本,将是Redis继支持Lua脚本之后的又一重磅 ...

  6. Monte Carlo方法简介(转载)

    Monte Carlo方法简介(转载)       今天向大家介绍一下我现在主要做的这个东东. Monte Carlo方法又称为随机抽样技巧或统计实验方法,属于计算数学的一个分支,它是在上世纪四十年代 ...

  7. C#——Marshal.StructureToPtr方法简介

    目录 MarshalStructureToPtr方法简介 功能及位置 语法 参数说明 异常 备注 举例 本博客(http://blog.csdn.net/livelylittlefish)贴出作者(三 ...

  8. Fatal error: Using $this when not in object context in 解决方法

    Fatal error: Using $this when not in object context in 解决方法 粗心造成的错误 $this 只存在于下面情况 $obj = new object ...

  9. TabBarController创建及使用方法简介

    TabBarController创建及使用方法简介 大致讲解一下TabBarController的创建过程: 首先,我们需要一些视图,如创建UIControllerView类型的view1,view2 ...

随机推荐

  1. ORA-09925: Unable to create audit trail file

    当我修改ORACLE_SID为新的SID,想进行数据库还原时,用sqlplus报如下错误 [oracle@dbtest ~]$ sqlplus / as sysdba SQL Production : ...

  2. 百度网盘背后的存储系统atlas

    原文  http://www.bitstech.net/2015/07/25/baidu-atlas/   百度网盘免费提供2TB存储, 它的存储量一定是惊人的, 支持它的存储系统atlas也是相当不 ...

  3. 为什么API多用C而不是C++,为什么C++程序大多不使用异常

    读Defective C++随笔 不尽知用兵之害者,则不能尽知用兵之利也 ——<孙子兵法> 1.为什么API多用C而不是C++以前就一直很奇怪,为什么API大都用C的方式提供,即使有C++ ...

  4. 【MyEclipse常见错误】-java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory的解决

    ApacheJavaTomcatMyeclipse  自己前一段时间出现了这个问题,通过在网上搜索,大概知道了原因,整理下一,以供大家参考. 将项目部署好后,启动tomcat后报错,java.lang ...

  5. Delphi 10.2 Tokyo的新特性

    Delphi 10.2(Tokyo)出来一段时间了,最重要的新特性就是支持Linux的服务端. 官网有详细的介绍: 这里是主要的特性介绍:https://www.embarcadero.com/pro ...

  6. flask(四)

    1.Flask-Session from flask import session,Flask from flask_session import Session #导入 from redis imp ...

  7. python代码检查工具pylint 让你的python更规范

    1.pylint是什么? Pylint 是一个 Python 代码分析工具,它分析 Python 代码中的错误,查找不符合代码风格标准(Pylint 默认使用的代码风格是 PEP 8,具体信息,请参阅 ...

  8. IIS7上传4M文件以上文件出现“Post大小超出允许的限制”错误解决方法

    在web.config文件中的system.web节点中添加如下这句,即40M <system.web> <httpRuntime maxRequestLength = " ...

  9. 重磅发布:阿里开源 OpenJDK 长期支持版本 Alibaba Dragonwell

    原文地址:https://yq.aliyun.com/articles/694603 本文作者:阿里开源  本文来自云栖社区合作伙伴"阿里系统软件技术",了解相关信息可以关注&qu ...

  10. 吐槽:那些Java设计中不得不说的槽点

    1. 求长度各有千秋 你是否曾经在面试的时候,经常被问到:数组有没有 length() 方法?字符串有没有 length() 方法? 集合有没有 length() 方法? 面对这个问题,那么不得不吐槽 ...