React Context详解使用方法

目录
  • 一、概述
  • 二、API
    • React.createContext
    • Context.Provider
    • Class.contextType
    • Context.Consumer
    • Context.displayName
  • 三、使用
    • 1.自定义Context (类组件中使用)
    • 2.使用Consumer支持获取多个Context上的值
    • 3.useContext使用(函数式组件中使用)

一、概述

  • Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
  • 如果多个组件中都需要这个值 或者 获取值和使用值的层级相隔很远,就可以使用Context(上下文)来共享数据。
  • 如:地区偏好,UI 主题、当前认证的用户、语言等
  • 谨慎使用,这会使组件的复用性变差

二、API

React.createContext

const MyContext = React.createContext(defaultValue)
  • 创建一个 Context 对象
  • 提供一个默认值,只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效

Context.Provider

  const MyContext = React.createContext(defaultValue)
  <MyContext.Provider value={xxx}> ... </MyContext.Provider>
  • 每个 Context 对象都会返回一个 Provider React 组件
  • Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以对应多个消费组件。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据
  • value 值发生变化时,它内部的所有消费组件都会重新渲染

Class.contextType

class MyClass extends React.Component {
  componentDidMount() {
    let value = this.context;
    /* 在组件挂载完成后,使用 MyContext 组件的值来执行一些有副作用的操作 */
  }
  componentDidUpdate() {
    let value = this.context;
    /* ... */
  }
  componentWillUnmount() {
    let value = this.context;
    /* ... */
  }
  render() {
    let value = this.context;
    /* 基于 MyContext 组件的值进行渲染 */
  }
}
MyClass.contextType = MyContext;
  • 挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象
  • 可以在任意生命周期中访问

Context.Consumer

<MyContext.Consumer>
   {value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>
  • 消费组件(子组件)中使用value
  • 函数作为子元素;这个函数接收当前的 context 值,返回一个 React 节点。传递给函数的 value 值等同于往上组件树离这个 context 最近的 Provider 提供的 value 值。如果没有对应的 Provider,value 参数等同于传递给 createContext() 的 defaultValue。

Context.displayName

const MyContext = React.createContext()
MyContext.displayName = 'MyDisplayName'
<MyContext.Provider> //在 DevTools 中显示的标签:MyDisplayName.Provider
<MyContext.Consumer>//在 DevTools 中显示的标签:MyDisplayName.Consumer
//如果没有 MyContext.displayName = 'MyDisplayName' ,则显示Context.Provider、Context.Consumer

在 DevTools 中需要显示的内容

三、使用

1.自定义Context (类组件中使用)

//ThemeContext.js
import React from 'react'
export const ThemeContext = React.createContext('light')
//themed-button.js
//在需要的位置使用 Class.contextType
import React, { Component } from 'react';
import ThemeContext from "./context/ThemeContext.js";

class ThemedButton extends Component {
	static contextType = ThemeContext;
	render() {
		return <button>{this.context}</button>;
	}
}
export default ThemedButton
//app.js
//上下文包裹组件 Context.Provider
import ThemeContext from './context/ThemeContext.js';
import ThemedButton from './ThemedButton.js';
import './App.css';
function App() {
  return (
    <ThemeContext.Provider value='dark'> //dark将默认值light覆盖
      <div className="App">
        <header className="App-header">
          <ThemedButton />
        </header>
      </div>
    </ThemeContext.Provider>
  );
}
export default App;

2.使用Consumer支持获取多个Context上的值

需要多个上下文的值时可以使用Consumer

//ThemeContext.js
import React from 'react'
const ThemeContext = React.createContext('light')
ThemeContext.displayName = 'ThemeContext'
export default ThemeContext
//UserContext.js
import React from 'react'
const UserContext = React.createContext('guest')
UserContext.displayName = 'UserContext'
export default UserContext
//app.js
//使用Provider赋值:
import React, { Component } from 'react';
import ThemeContext from './context/ThemeContext.js';
import UserContext from './context/UserContext.js';
import ThemedButton from './ThemedButton.js';
import './App.css';
class App extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
        <ThemeContext.Provider value={'dark'}>
          <div className="App">
            <UserContext.Provider value={'user'}>
              <header className="App-header">
                <ThemedButton />
              </header>
            </UserContext.Provider>
          </div>
        </ThemeContext.Provider>
    );
  }
}
export default App
//themed-button.js
import React, { Component } from 'react';
import ThemeContext from "./context/ThemeContext.js";
import UserContext from "./context/UserContext.js";
class ThemedButton extends Component {
	render() {
		return (
			<>
				<ThemeContext.Consumer>
					{theme => <div>{theme}</div>}
				</ThemeContext.Consumer>
				<UserContext.Consumer>
					{user => <div>{user}</div>}
				</UserContext.Consumer>
			</>
		);
	}
}
export default ThemedButton

3.useContext使用(函数式组件中使用)

react原生Hook ,让函数式组件也可以使用Context,而且支持多个不同类型的context

//ThemeContext.js
import React from 'react'
const ThemeContext = React.createContext('light')
ThemeContext.displayName = 'ThemeContext'
export default ThemeContext
//UserContext.js
import React from 'react'
const UserContext = React.createContext('guest')
UserContext.displayName = 'UserContext'
export default UserContext
//app.js
//使用Provider赋值:
import React, { Component } from 'react';
import ThemeContext from './context/ThemeContext.js';
import UserContext from './context/UserContext.js';
import ThemedButton from './ThemedButton.js';
import './App.css';
const App = () => {
  render() {
    return (
        <ThemeContext.Provider value={'dark'}>
          <div className="App">
            <UserContext.Provider value={'user'}>
              <header className="App-header">
                <ThemedButton />
              </header>
            </UserContext.Provider>
          </div>
        </ThemeContext.Provider>
    );
  }
}
export default App
//themed-button.js
import { useContext } from 'react'
import ThemeContext  from './context/ThemeContext'
import UserContext from './context/UserContext'
const ThemedButton = () => {
 const theme = useContext(ThemeContext)
 const user = useContext(UserContext)
 return (
    <>
		<div>{theme}</div>
		<div>{user}</div>
	</>
 )
}
export default ThemedButton

到此这篇关于React Context详解使用方法的文章就介绍到这了,更多相关React Context内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • React Context源码实现原理详解

    目录 什么是 Context Context 使用示例 createContext Context 的设计非常特别 useContext useContext 相关源码 debugger 查看调用栈 什么是 Context 目前来看 Context 是一个非常强大但是很多时候不会直接使用的 api.大多数项目不会直接使用 createContext 然后向下面传递数据,而是采用第三方库(react-redux). 想想项目中是不是经常会用到 @connect(...)(Comp) 以及 <Pro

  • React Context 变迁及背后实现原理详解

    目录 Context 老的 Context API 基础示例 context 中断问题 解决方案 新的 Context API 基础示例 模拟实现 createContext 源码 Context 本篇我们讲 Context,Context 可以实现跨组件传递数据,大部分的时候并无需要,但有的时候,比如用户设置 了 UI 主题.地区偏好,如果从顶层一层层往下传反而有些麻烦,不如直接借助 Context 实现数据传递. 老的 Context API 基础示例 在讲最新的 API 前,我们先回顾下老

  • React Context原理深入理解源码示例分析

    目录 正文 一.概念 二.使用 2.1.React.createContext 2.2.Context.Provider 2.3.React.useContext 2.4.Example 三.原理分析 3.1.createContext 函数实现 3.2. JSX 编译 3.3.消费组件 - useContext 函数实现 3.4.Context.Provider 在 Fiber 架构下的实现机制 3.5.小结 四.注意事项 五.对比 useSelector 正文 在 React 中提供了一种「

  • React Context详解使用方法

    目录 一.概述 二.API React.createContext Context.Provider Class.contextType Context.Consumer Context.displayName 三.使用 1.自定义Context (类组件中使用) 2.使用Consumer支持获取多个Context上的值 3.useContext使用(函数式组件中使用) 一.概述 Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法. 如果多个组件中都需

  • 如何在原有Android项目中快速集成React Native详解

    前言 RN经过一段时间发展,已经有充分数量的人尝试过了,就我身边就有几批,褒贬也不一: ① 做UI快 ② 还是有很多限制,不如原生Native ③ 入门简单,能让前端快速开发App ④ iOS&Android大部分代码通用 ⑤ code-push能做热更新,但是用不好依旧坑 ...... 在得到一些信息后,可以看出,要用RN高效率的做出比较不错的App是有可能的,单看投入度与最初设计是否合理,而且现在关于React Native的各种文档是相当丰富的,所以这个阶段想切入RN可能是一个不错的选择.

  • 一篇Vue、React重点详解大全

    目录 Vue 生命周期 MVVM 双向绑定原理 虚拟dom v-for为什么要用key nextTick v-show.v-if的区别 vue单页面应用如何首页优化 Vue 的父组件和子组件生命周期钩子执行顺序是什么 Vue 中的 computed 是如何实现的 React 不同之处 vue和react的区别 Vue 生命周期 vue2: 总共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后. 创建前/后: 在beforeCreate阶段,由于还未初始化,vue实例的挂载元素el和数

  • C#动态对象(dynamic)详解(实现方法和属性的动态)

    C#的动态对象的属性实现比较简单,如果要实现动态语言那种动态方法就比较困难,因为对于dynamic对象,扩展方法,匿名方法都是不能用直接的,这里还是利用对象和委托来模拟这种动态方法的实现,看起来有点javascript的对象味道: 1) 定义一个委托,参数个数可变,参数都是object类型:这里的委托多有个dynamic参数,代表调用这个委托的动态对象本身. public delegate object MyDelegate(dynamic Sender, params object[] PMs

  • 详解python方法之绑定方法与非绑定方法

    写在之前 在 Python 的类里面除了属性之外,还有方法,当然也有文档和注释这类东西,但是这个只是人来看,计算机则不关心.我们之前说过,我们一般用实例调用方法,既然我们说了是一般,那么就说明还有其他调用方法的方式,今天我们就来说一下「绑定方法和非绑定方法」. 绑定方法和非绑定方法 在 Python 中除了特殊方法以外,类中的其他普通方法也是经常用到的,所以对于普通的方法也要进行研究,下面我们来看一个例子: >>> class Sample: ... def f(self): ... p

  • 详解Java方法method的定义与调用及重载

    目录 方法的定义和调用 什么是方法 方法的声明格式 方法的调用方式 方法的详细说明 总结 方法的重载 什么是方法重载 构成方法重载的条件 总结 方法的定义和调用 什么是方法 方法(method)就是一段用来完成特定功能的代码片段,类似于其它语言的函数(function). 方法用于定义该类或该类的实例的行为特征和功能实现. 方法是类和对象行为特征的抽象.方法很类似于面向过程中的函数.面向过程中,函数是最基本单位,整个程序由一个个函数调用组成.面向对象中,整个程序的基本单位是类,方法是从属于类和对

  • JAVA SPI机制详解使用方法

    目录 写在前面 什么是SPI 使用场景 实现约定 四种角色 基于JAVA原生特性实现的JAVA SPI机制的DEMO 1. 主要角色 2. 示例代码 3. 说明 基于SPRING BOOT实现的JAVA SPI机制的DEMO 写在前面 Java SPI提供了一种为某个接口寻找服务实现的机制.有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,SPI的核心思想就是解耦. 什么是SPI SPI全称Service Provider Interface,是Java提供的

  • Python NumPy矩阵对象详解及方法

    目录 1. 介绍 2. 创建矩阵 3. 矩阵特有属性 4. 矩阵乘法 1. 介绍 在数学上,矩阵(Matrix)是一个按照矩形阵列排列的负数或实数集合,但在NumPy中,矩阵np.matrix是数组np.ndarray的派生类.这意味着矩阵本质上是   一个数组,拥有数组的所有属性和方法:同时,矩阵又有一些不同于数组的特性和方法首先,矩阵是二维的,不能像数组一样幻化成任意维度,即使展开或切片,返回也是二维的:其次,矩阵和矩阵.矩阵和数组都可以做加减乘除运算,运算结果都是返回矩阵:最后,矩阵的乘法

  • JavaScript 函数节流详解及方法总结

    JavaScript 函数节流详解 浏览器一个网页的UI线程只有一个,他同时会处理界面的渲染和页面JavaScript代码的执行(简单扩展一下,浏览器或者JavaScript运行大环境并不是单线程,诸如ajax异步回调.hybrid框架内与native通信.事件队列.CSS运行线程等等都属于多线程环境,不过ES6引入了Promise类来减少了部分异步情况).因此当JavaScript代码运行计算量很大的方法时,就有可能阻塞UI线程,小则导致用户响应卡顿,严重的情况下浏览器会提示页面无响应是否强制

  • 详解C#方法中使用out参数做登录判断代码实例

    本文实例为大家分享了C#使用out参数做登录判断的具体代码,供大家参考,具体内容如下 static void Main(string[] args) { //分别提示用户输入用户名和密码 //写一个方法来判断用户输入的是否正确 //返回给用户一个登陆结果,并且还要单独的返回给用户一个登陆信息 //如果用户密或码错误,除了返回登陆结果之外,还要返回一个 "用户名错误"或"密码错误" //如果用户密码都错误则返回"未知错误" Console.Writ

随机推荐