Taro React ---- 在函数组件或类组件中访问上下文(Context)中的值

news2025/2/27 14:07:51

1. 解决问题的场景

项目是开发好几年了,当时采用的是类组件开发。现在新增需求,新增需求使用的函数组件,组件涉及的层级比较多,如果直接组件传值,比较麻烦。但是单独为这次的需求新增 redux 的引入又觉得没必要。然后在即需要一个页面全局状态统一管理的地方,又不希望进行组件一级一级的传值,不方便维护。最后想到了访问上下文(Context)中的值的方法解决问题。

1. 方案一:父组件为类组件访问上下文

2. 父组件为类组件访问上下文

  1. ClassCreateContext 创建上下文;
  2. HookChildContext 函数组件使用 useContext 访问上下文;
  3. ClassChildContext 类组件使用 static contextType 访问上下文;
  4. ClassConsumerContext 类组件使用 <XxxContext.Consumer> 访问上下文;
  5. 父组件 count 变量;
  6. 父组件修改 count 的操作函数 updateCount;
  7. 创建上下文并提供值 ClassCreateContext.Provider。
import React, { Component } from "react";
import Taro from "@tarojs/taro";
import { View } from "@tarojs/components";
import { ClassCreateContext } from './classCreateContext';
import HookChildContext from './hookChildContext';
import ClassChildContext from './classChildContext';
import ClassConsumerContext from './classConsumerContext';

class ClassContext extends Component {
  constructor(props) {
    super(props);
  }
  state = {  
    count: 0
  }
  // 修改count的值
  updateCount = (type = 'add') => {
    let { count } = this.state;
    count = {
      'add': () => {
        return ++count
      },
      'minus': () => {
        return --count
      }
    }[type]?.()
    this.setState({count})
  }
  render() { 
    let { count } = this.state;
    return <View>
      {/* 类组件的父组件的变量显示和操作 */}
      <View>父组件 count: {count}</View>
      <View className='rui-flex-ac'>
        <View 
          className='rui-fg rui-flex-cc' 
          onClick={this.updateCount.bind(this,'add')}>加</View>
        <View 
          className='rui-fg rui-flex-cc'
          onClick={this.updateCount.bind(this,'minus')}>减</View>
      </View>
      {/* 创建上下文并提供值 */}
      <ClassCreateContext.Provider value={{ count, updateCount: this.updateCount }}>
        {/* 类组件中使用函数组件访问上下文 */}
        <HookChildContext/>
        {/* 类组件中使用类组件使用 static contextType 访问上下文 */}
        <ClassChildContext/>
        {/* 类组件中使用类组件使用 <XxxContext.Consumer> 访问上下文 */}
        <ClassConsumerContext/>
      </ClassCreateContext.Provider>
    </View>;
  }
}

export default ClassContext;

3. 特别注意类组件的操作函数

  // 修改count的值
  updateCount = (type = 'add') => {
    let { count } = this.state;
    count = {
      'add': () => {
        return ++count
      },
      'minus': () => {
        return --count
      }
    }[type]?.()
    this.setState({count})
  }

类组件的父组件的操作函数必须使用箭头函数,因为类组件涉及到函数内部 this 的指向问题,当然我们也可以使用 bind、call、aplly 来解决这个问题,但是我认为此处直接使用箭头函数,直接指向的是当前类组件,这样我们就不用关心在子组件调用操作方法时 this 的指向问题!!!

4. 类组件创建上下文

classCreateContext.js

import { createContext } from "react";
// 创建类组件的上下文
export const ClassCreateContext = createContext({});

5. 函数组件实现访问上下文和修改上下文值 HookChildContext

  1. 引入创建的上下文 ClassCreateContext;
  2. 使用 useContext 访问上下文的值和修改值得操作方法;
  3. 在组件 HookChildContext 中展示访问的上下文值 count;
  4. 在组建 HookChildContext 中操作访问的上下文值的方法 updateCount。
import { View, Text, Image } from '@tarojs/components';
import { useContext } from 'react';
import { ClassCreateContext } from './classCreateContext';

const HookChildContext = (props) => {
  let { count, updateCount } = useContext(ClassCreateContext)
  return <View>
    <View>函数组件【HookChildContext】</View>
    <View>获取上下文 count: {count}</View>
    <View>修改父组件的 count</View>
    <View className='rui-flex-ac'>
      <View 
        onClick={updateCount.bind(null, 'add')}
        className='rui-flex-cc rui-fg'>hook 加</View>
      <View 
        onClick={updateCount.bind(null, 'minus')}
        className='rui-flex-cc rui-fg'>hook 减</View>
    </View>
  </View>
}
export default HookChildContext;

6. 类组件实现访问上下文和修改上下文值 ClassChildContext

  1. 引入创建的上下文 ClassCreateContext;
  2. 使用 static contextType 访问上下文的值和修改值得操作方法;
  3. 在组件 ClassChildContext 中展示访问的上下文值 count;
  4. 在组建 ClassChildContext 中操作访问的上下文值的方法 updateCount。
import React, { Component } from "react";
import Taro from "@tarojs/taro";
import { View } from "@tarojs/components";
import { ClassCreateContext } from './classCreateContext';

class ClassChildContext extends Component {
  static contextType = ClassCreateContext;
  constructor(props) {
    super(props);
  }
  state = {  }
  render() { 
    let { count, updateCount } = this.context;
    return <View>
      <View>类组件【ClassChildContext】</View>
      <View>获取上下文 count: {count}</View>
      <View>修改父组件的 count</View>
      <View className='rui-flex-ac'>
        <View 
          onClick={updateCount.bind(null, 'add')}
          className='rui-flex-cc rui-fg'>class 加</View>
        <View 
          onClick={updateCount.bind(null, 'minus')}
          className='rui-flex-cc rui-fg'>class 减</View>
      </View>
    </View>;
  }
}

export default ClassChildContext;

7. 类组件实现访问上下文和修改上下文值 ClassConsumerContext

  1. 引入创建的上下文 ClassCreateContext;
  2. 使用 <ClassCreateContext.Consumer> 访问上下文的值和修改值得操作方法;
  3. 在组件 ClassConsumerContext 中展示访问的上下文值 count;
  4. 在组建 ClassConsumerContext 中操作访问的上下文值的方法 updateCount。
import React, { Component } from "react";
import Taro from "@tarojs/taro";
import { View } from "@tarojs/components";
import { ClassCreateContext } from './classCreateContext';

class ClassConsumerContext extends Component {
  constructor(props) {
    super(props);
  }
  state = {  }
  render() { 
    return <ClassCreateContext.Consumer>
      {
        value => (
          <>
            <View>类组件【ClassConsumerContext】</View>
            <View>获取上下文 count: {value.count}</View>
            <View>修改父组件的 count</View>
            <View className='rui-flex-ac'>
              <View 
                onClick={value.updateCount.bind(null, 'add')}
                className='rui-flex-cc rui-fg'>consumer 加</View>
              <View 
                onClick={value.updateCount.bind(null, 'minus')}
                className='rui-flex-cc rui-fg'>consumer 减</View>
            </View>
          </>
        )
      }
    </ClassCreateContext.Consumer>;
  }
}

export default ClassConsumerContext;

8. 结果预览

输入图片说明

2. 方案二:父组件为函数组件访问上下文

9. 父组件为函数组件访问上下文

  1. HookCreateContext 创建上下文;
  2. HookSonContext 函数组件使用 useContext 访问上下文;
  3. ClassSonContext 类组件使用 static contextType 访问上下文;
  4. ClassSonConsumerContext 类组件使用 <XxxContext.Consumer> 访问上下文;
  5. 父组件 count 变量;
  6. 父组件修改 count 的操作函数 updateCount;
  7. 创建上下文并提供值 HookCreateContext.Provider。
import { View, Text, Image } from '@tarojs/components';
import { useState, useEffect } from 'react';
import { HookCreateContext } from './hookCreateContext';
import ClassSonContext from './classSonContext';
import HookSonContext from './HookSonContext';

const HookContext = (props) => {
  let [count, setCount] = useState(0)
  // 修改 count
  function updateCount(type='add'){
    count = {
      'add': () => {
        return ++count
      },
      'minus': () => {
        return --count
      }
    }[type]?.()
    setCount(count)
  }
  return <View>
    <View>父组件 count: {count}</View>
    <View className='rui-flex-ac'>
      <View 
        onClick={updateCount.bind(null, 'add')}
        className='rui-flex-cc rui-fg'>加</View>
      <View 
        onClick={updateCount.bind(null, 'minus')}
        className='rui-flex-cc rui-fg'>减</View>
    </View>
    <HookCreateContext.Provider value={{count, updateCount}}>
      <ClassSonContext/>
      <HookSonContext/>
    </HookCreateContext.Provider>
  </View>
}
export default HookContext;

10. 函数组件创建上下文

hookCreateContext.js

import { createContext } from "react";
// 创建函数组件的上下文
export const HookCreateContext = createContext({});

11. 类组件实现访问上下文和修改上下文值 ClassSonContext

  1. 引入创建的上下文 HookCreateContext;
  2. 使用 static contextType 访问上下文的值和修改值得操作方法;
  3. 在组件 ClassSonContext 中展示访问的上下文值 count;
  4. 在组建 ClassSonContext 中操作访问的上下文值的方法 updateCount。
import React, { Component } from "react";
import Taro from "@tarojs/taro";
import { View } from "@tarojs/components";
import { HookCreateContext } from './hookCreateContext';

class ClassSonContext extends Component {
  static contextType = HookCreateContext;
  constructor(props) {
    super(props);
  }
  state = {  }
  render() { 
    let { count, updateCount } = this.context;
    return <View>
      <View>类组件【ClassSonContext】</View>
      <View>获取上下文 count: {count}</View>
      <View>修改父组件的 count</View>
      <View className='rui-flex-ac'>
        <View 
          onClick={updateCount.bind(null, 'add')}
          className='rui-flex-cc rui-fg'>class 加</View>
        <View 
          onClick={updateCount.bind(null, 'minus')}
          className='rui-flex-cc rui-fg'>class 减</View>
      </View>
    </View>;
  }
}

export default ClassSonContext;

12. 函数组件实现访问上下文和修改上下文值 HookSonContext

  1. 引入创建的上下文 HookCreateContext;
  2. 使用 useContext 访问上下文的值和修改值得操作方法;
  3. 在组件 HookSonContext 中展示访问的上下文值 count;
  4. 在组建 HookSonContext 中操作访问的上下文值的方法 updateCount。
import { View, Text, Image } from '@tarojs/components';
import { useContext } from 'react';
import { HookCreateContext } from './hookCreateContext';

const HookSonContext = (props) => {
  let { count, updateCount } = useContext(HookCreateContext)
  return <View>
    <View>函数组件【HookSonContext】</View>
    <View>获取上下文 count: {count}</View>
    <View>修改父组件的 count</View>
    <View className='rui-flex-ac'>
      <View 
        onClick={updateCount.bind(null, 'add')}
        className='rui-flex-cc rui-fg'>hook 加</View>
      <View 
        onClick={updateCount.bind(null, 'minus')}
        className='rui-flex-cc rui-fg'>hook 减</View>
    </View>
  </View>
}
export default HookSonContext;

13. 结果预览

输入图片说明

14. 总结

  1. 创建上下文使用的是 createContext 方法;
  2. 使用 XxxContext.Provider 给上下文提供值;
  3. 在子组件是函数组件时,可以使用 useContext 访问上下文;
  4. 在子组件是类组件时,可以使用 static contextType 或者 <XxxContext.Consumer> 访问上下文;
  5. 如果是多界面子组件,建议还是传入值操作,访问上下文比较使用一个界面下的所有子组件访问上下文。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1477251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

优化照片分辨率:如何将照片调整为150dpi,以适应不同场景?

在数字化时代&#xff0c;我们经常需要在不同场景中使用照片&#xff0c;如打印、网页发布、社交媒体分享等。然而&#xff0c;不同场景对于照片的分辨率要求各不相同。有时&#xff0c;我们需要将照片的分辨率调整为特定数值&#xff0c;例如150dpi(每英寸点数)。这样做可以确…

flutter面试题及答案,android面试题最新

前言 今天想停下代码&#xff0c;写点脑袋里不断浮现出来的一些看法。 也就是最近在微博和知乎上老看到“互联网寒冬”的说法。要么是看到啥公司薪水无法如期发放了&#xff0c;要么是看到别人说什么“裁员了&#xff0c;没有交接&#xff0c;签字然后电脑还了就走人&#xf…

【JavaEE进阶】 Spring AOP快速上手

文章目录 &#x1f343;什么是AOP&#x1f333;什么是Spring AOP&#x1f334;上手Spring AOP&#x1f6a9;引入依赖&#x1f6a9;编写AOP程序 ⭕总结 &#x1f343;什么是AOP AOP是Aspect Oriented Programming的简称&#xff08;又称为面向切⾯编程&#xff09; 什么是面向…

【k8s 访问控制--认证与鉴权】

1、身份认证与权限 前面我们在操作k8s的所有请求都是通过https的方式进行请求&#xff0c;通过REST协议操作我们的k8s接口&#xff0c;所以在k8s中有一套认证和鉴权的资源。 Kubenetes中提供了良好的多租户认证管理机制&#xff0c;如RBAC、ServiceAccount还有各种策路等。通…

练习 1 Web EasySQL极客大挑战

CTF Week 1 EasySQL极客大挑战 BUUCTF 典中典复习 Web SQL 先尝试输入&#xff0c;找一找交互页面 check.php 尝试万能语句 a’ or true SQL注入&#xff1a;#和–的作用 get传参只能是url编码&#xff0c;注意修改编码&#xff0c;输入的字符串要改成url格式。 POST请求和…

定制红酒:定制过程中的沟通与调整,确保满足您的需求

在云仓酒庄洒派的定制红酒服务中&#xff0c;沟通与调整是确保满足消费者需求的关键环节。为了提供上好的服务&#xff0c;云仓酒庄洒派非常重视与消费者的沟通&#xff0c;并根据他们的反馈进行调整&#xff0c;以确保产品符合他们的期望。 首先&#xff0c;在定制过程中&…

Fastjson2 <== 2.0.26反序列漏洞

根据Y4TACKER师傅在2023-03-20发布了一篇关于Fastjson原生反序列化的文章&#xff0c;文章中引入注目的是利用条件限制条件&#xff0c;不常常关注漏洞预警或者内容的几乎都是未发觉Fastjson2 到Fastjson2 2.0.26版本都有问题&#xff0c;其实如果单独去使用一些关键词去搜索&a…

linux系统---nginx基础

目录 一、Nginx的概念 二、Nginx常用功能 1、HTTP(正向)代理&#xff0c;反向代理 1.1正向代理 1.2 反向代理 2、负载均衡 2.1 轮询法&#xff08;默认方法&#xff09; 2.2 weight权重模式&#xff08;加权轮询&#xff09; 2.3 ip_hash 3、web缓存 三、基础特性 四…

【深度优先搜索】【图论】【推荐】332. 重新安排行程

作者推荐 动态规划的时间复杂度优化 本文涉及知识点 深度优先搜索 图论 LeetCode332. 重新安排行程 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票都属于一个从 JFK&a…

flutter通知栏,写得太好了

【1面 - 基础面】 你们 Android 开发的时候&#xff0c;对于 UI 稿的 px 是如何适配的&#xff1f; dpi&#xff1a;屏幕像素密度&#xff0c;指的是在系统软件上指定的单位尺寸的像素数量&#xff0c;它往往是写在系统出厂配置文件的一个固定值&#xff1b;ppi&#xff1a;也…

骨传导耳机什么牌子的好?揭秘成功法则与避坑策略

科技进步带来了骨传导耳机的兴起&#xff0c;这种耳机以其独特的优势而受到越来越多消费者的青睐。与传统的入耳式相比&#xff0c;骨传导耳机通过骨头传递声音&#xff0c;避免了对耳道的直接压迫&#xff0c;减少了对听力的潜在伤害。同时它们允许用户在享受音乐的同时&#…

Python并发编程:多线程与多进程的区别

一 谁的开启速度快 1. 在主进程下开启线程 1 2 3 4 5 6 7 8 9 from threading import Thread def work(): print("hello") if __name__ __main__: t Thread(targetwork) t.start() print("主线程/主进程") 执行结果如下&#xff1a…

十分钟三个步骤给百万级数据Excel多人同时导出添加排队导出功能,避免干崩服务器

业务场景 考虑到数据库数据日渐增多&#xff0c;导出会有全量数据的导出&#xff08;甚至有的时候数据百万级&#xff09;&#xff0c;多人同时导出可以会对服务性能造成影响&#xff0c;导出涉及到mysql查询的io操作&#xff0c;还涉及文件输入、输出流的io操作&#xff0c;所…

算法day02_209.长度最小的子数组

推荐阅读 从零开始学数组&#xff1a;深入浅出&#xff0c;带你掌握核心要点 初探二分法 再探二分法 目录 推荐阅读209.长度最小的子数组题目思路解法暴力解法队列相加法&#xff08;滑动窗口&#xff09;对列相减法&#xff08;滑动窗口&#xff09; 系统的纪录一下刷算法的过…

特斯拉一面算法原题

来自太空的 X 帖子 埃隆马斯克&#xff08;Elon Musk&#xff09;旗下太空探索技术公司 SpaceX 于 2 月 26 号&#xff0c;从太空往社交平台 X&#xff08;前身为推特&#xff0c;已被马斯克全资收购并改名&#xff09;发布帖子。 这是 SpaceX 官号首次通过星链来发送 X 帖子&a…

Rocky Linux 运维工具yum

一、yum的简介 ​​yum​是用于在基于RPM包管理系统的包管理工具。用户可以通过 ​yum​来搜索、安装、更新和删除软件包&#xff0c;自动处理依赖关系&#xff0c;方便快捷地管理系统上的软件。 二、yum的参数说明 1、install 用于在系统的上安装一个或多个软件包 2、seach 用…

React中使用useActive

1.引入 import { useActivate } from "react-activation";2.React Activation 在React中使用react-activation,其实就是类似于Vue中的keep-alive&#xff0c;实现数据的缓存&#xff1b; 源码&#xff1a; import { ReactNode, ReactNodeArray, Context, Component…

密码学在 Web3 钱包中的应用:私钥是什么?bitget钱包为例

在非对称加密演算法中&#xff0c;私钥是一串随机生成的数字&#xff0c;通常以十六进制数表示&#xff08;也就是由0、1、2、3、4、5、6、7、8、9、a、b、c、d、e和f组成&#xff09;。私钥生成后&#xff0c;这串数字被作为一个单向数学函数中的输入值&#xff0c;计算产生的…

python web框架fastapi模板渲染--Jinja2使用技巧总结

文章目录 1.jinja2模板1.1、jinja2 的变量1.1.1 列表类型数据渲染1.1.2 字典类型数据渲染 2. jinja2 的过滤器3. jinja2 的控制结构3.1、分支控制3.2、循环控制 1.jinja2模板 要了解jinja2&#xff0c;那么需要先理解模板的概念。模板在Python的web开发中⼴泛使⽤&#xff0c;…

Python多线程编程:深入理解threading模块及代码实战【第99篇—Multiprocessing模块】

Python多线程编程&#xff1a;深入理解threading模块及代码实战 在Python编程中&#xff0c;多线程是一种常用的并发编程方式&#xff0c;它可以有效地提高程序的执行效率&#xff0c;特别是在处理I/O密集型任务时。Python提供了threading模块&#xff0c;使得多线程编程变得相…