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. ExtJS 折线图趟过的坑

    问题: 1.根据条件检索后绘制折线图,之前的坐标没有清除如图 解决方案: 在绘制之前,清空坐票: leftLine.surface.removeAll(); leftLine.redraw(false ...

  2. UWP中弹出框屏幕适配问题

    上次在UWP中的消息提示框(二)中谈到弹出框在虚拟导航栏的手机上被遮挡问题,今天接就着扯. 上次给用户控件指定的宽高都是Window.Current.Bounds的宽高,而这个获取到的是包含应用程序窗 ...

  3. C++ Builder 控件的卸载

    控件卸载: 1.选择   BCB   菜单   File→Close   All   (关闭所有文件)     选择BCB   菜单:   Project→Options→Packages   在   ...

  4. php生成html静态文件

    现在的动态网站存在很多性能上的弊端,seo优化会存在一定的瓶颈,现在将动态的网站代码转换为html静态文件,是浏览器通过html间接的读取动态网站源文件,这对其网站加载速度还是seo优化有着举足轻重的 ...

  5. linux下安装Nginx1.16.0

    因为最近在倒腾linux,想安装新版本的nginx,找了一圈教程没有找到对应的教程,在稍微倒腾了一会之后终于成功的安装了最新版. 服务器环境为centos,接下来是详细步骤: 安装必要依赖插件 yum ...

  6. Netty源码分析--初始化Options,添加处理器(四)

    接上篇,我们继续进入AbstractBootstrap类的 initAndRegister() 方法 进入init()方法 设置父级Channel的options, 进入到上节提到的NioServer ...

  7. http-get调用接口简单代码

    一.简单便捷的httpget调用接口,并且返回接口数据1.导入相应的jar包: 2.代码如下: HttpGet get=null; try {HttpClient httpClient = new D ...

  8. Storm 学习之路(九)—— Storm集成Kafka

    一.整合说明 Storm官方对Kafka的整合分为两个版本,官方说明文档分别如下: Storm Kafka Integration : 主要是针对0.8.x版本的Kafka提供整合支持: Storm ...

  9. js获取radio选中索引值

    <form name="form1" onsubmit="return foo()"> <input type="radio&quo ...

  10. 【疑难杂症】windows下如何有效重装印象笔记

    重装这么简单的操作还用得着写篇文章吗??emmmm,言之有理,简单的重装就是卸载后重新下载最新的安装包然后安装就完事了,这里说的肯定是不简单的重装[滑稽]. 背景是这样的,之前在mac上对印象笔记的笔 ...