React【Context_作用、函数组件订阅Context、Fragments 、错误边界_概念 、错误边界_应用、Refs DOM】(四)

news2024/11/24 14:30:54

目录

Context_作用

函数组件订阅Context

Fragments

 错误边界_概念

 错误边界_应用

Refs & DOM


Context_作用

 React组件中数据是通过 props 属性自上而下(由父及子)进行传递的,但是有的时候中间的一些组件可能并不需要props的值。

//App.js
return (
    <div>
      <ContextTest />
    </div>
 );
//ContextTest.js
import React from 'react'
import NavBar from './NavBar'
export default class ContextTest extends
React.Component{
    constructor(props){
        super(props)
        this.state={user:{name:'小童',account:'baizhan'}}
   }
    render(){
        return <div>
            <NavBar user={this.state.user}/>
        </div>
   }
}
//NavBar.js
import React, { Component } from 'react'
import UserInfo from './UserInfo'
export default class NabBar extends
Component {
  render() {
    return (
      <div style= {{height:'50px',background:'#ccc',display:'flex',justifyContent:'space-around',alignItems:'center'}}>
       NabBar的内容
        <UserInfo user={this.props.user}/>
        </div>
   )
 }
}

//UserInfo.js
import React, { Component } from 'react'
export default class UserInfo extends
Component {
  render() {
    return (
      <div>你好,欢迎 {this.props.user.account}</div>
   )
 }
}

Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
 

何时使用 Context

如果我们要在组件树中去共享某些数据,并且要避免通过中间元素传递 props,则可以使用Context来实现。

Context_应用


 1、创建Context对象

React.createContext(defaultValue)

const MyContext = React.createContext(defaultValue);

2、 Context 的 Provider 组件

Contenxt的Provider组件用来提供其它组件要共享的数据。
设置 value 属性来设置要共享的数据。

<MyContext.Provider value={/* 某个值 */}>

3、Context 的 Provider 组件

Contenxt的Provider组件用来提供其它组件要共享的数据。
设置 value 属性来设置要共享的数据。

<MyContext.Provider value={/* 某个值 */}>

提示:我们把要使用共享数据的组件称为 消费组件 。

 Class.contextType

为组件类添加 contextType 属性,从而获取Context对象。

MyClass.contextType = MyContext;

提示:
挂载在 class 上的 contextType 属性会被重赋值为一个由
React.createContext() 创建的 Context 对象。这能让你使用 this.context 来消费最近 Context 上的那个值。
你可以在任何生命周期中访问到它,包括 render 函数中。

//MyContext.js
import React from "react";


export default
React.createContext({name:'',account:'xxx'})

//ContextTest.js
import React from 'react'
import MyContext from './MyContext'
import NavBar from './NavBar'
export default class ContextTest extends
React.Component {
    constructor(props) {
        super(props)
        this.state = { user: { name: '小童',account: 'xiaotong' } }
   }
    
    render() {
        return <div>
             {/* 使用Provider组件提供数据 */}
            <MyContext.Provider value= {this.state.user }>
                <NavBar />
            </MyContext.Provider>
        </div>
   }
}
//NabBar.js
import React, { Component } from 'react'
import UserInfo from './UserInfo'
export default class NabBar extends
Component {
  render() {
    return (
      <div style= {{height:'50px',background:'#ccc',display:'flex',justifyContent:'space-around',alignItems:'center'}}>
        NabBar的内容
        <UserInfo />
        
        </div>
   )
 }
}
//UserInfo.js
import React, { Component } from 'react'
import MyContext from './MyContext'

export default class UserInfo extends
Component {
  render() {
    console.log(this.context)
    return (
      <div>你好,欢迎 {this.context.account}</div>
   )
 }
}
//设置类的contentType属性,从而获取context对象
UserInfo.contextType=MyContext

函数组件订阅Context


 

 Context.Consumer

<MyContext.Consumer>
 {value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>
//ContextTest.js
render() {
        return <div>
           {/* 使用Provider组件提供数据 */}
            <MyContext.Provider value= {this.state.user }>
                <NavBar />
                <MyContext.Consumer>
                   {value=><div>
                        <h3>函数组件</h3>
                       获取到的账户:{value.account}
                        </div>}
                    
                </MyContext.Consumer>
              
            </MyContext.Provider>
            
        </div>
   }

Context更新
当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。
 

//ContextTest.js
render() {
        return <div>
            <button onClick= {()=>this.setState({user:{name:"xiaotong",account:'xiaotong123'}})}>更新user</button>
           {/* 使用Provider组件提供数据 */}
            <MyContext.Provider value={this.state.user }>
                <NavBar />
                <MyContext.Consumer>
                   {value=><div>
                        <h3>函数组件</h3>
                       获取到的账户:{value.account}
                        </div>}
                    
                </MyContext.Consumer>
              
            </MyContext.Provider>
            
        </div>
   }

 提示:消费组件是否重新渲染不受shouldComponentUpdate的控制。
其父组件使用shouldComponentUpdate停止了渲染或者消费组件本身使用shouldComponentUpdate停止渲染,也不影响消费组件的继续更新。
 

//NavBar.js
export default class NabBar extends
Component {
  shouldComponentUpdate(){
      //当前这个非消费组件会停止更新渲染,但是它的子组件UserInfo是Context的消费组件,还会继续更新
    return false
 }
  render() {
    console.log('navbar')
    return (
      <div style= {{height:'50px',background:'#ccc',display:'flex',justifyContent:'space-around',alignItems:'center'}}>
       NabBar的内容
        <UserInfo />
        
        </div>
   )
 }
}

//UserInfo.js
import React, { Component } from 'react'
import MyContext from './MyContext'
export default class UserInfo extends
Component {
    shouldComponentUpdate() {
        //虽然返回了false,但是context的值发生变化了,我还是要重新渲染的
        return false
   }
    render() {
        return (
            <div>你好,欢迎{this.context.account}</div>
       )
   }
}
UserInfo.contextType = MyContext

Fragments

 场景一:

render() {
    return (
      <p></p>
      <p></p>
   )
 }

提示: react当中,组件的界面只能有一个根标签。

 场景二:

render() {
    return (
        // 最外层的这个div可能根本不需要,不想让它渲染到页面上
        <div>
             <p></p><p></p>
        </div>
    
   )
 }

Fragments 允许你将子元素包裹在一起,而无需向 DOM 添加额外节点。
 

render() {
    return (
   <React.Fragment>
      <p></p>
      <p></p>
   </React.Fragment>
   )
 }

最终页面渲染结果:

1、Fragments 短语法

使用 <></> 代替 <React.Fragment></React.Fragment>

render() {
    return (
   <>
      <p></p>
      <p></p>
   </>
   )
 }

提示:
因为Fragments最终不会被渲染为DOM,所以不要在Framents上面绑定事件或者设置一些其它属性,目前只支持设置key属性。

 错误边界_概念

 通常某一个组件中发生的错误会导致整个应用崩溃,页面一片空白。

//App.js
render() {
    return (
      <>
        <ContextTest />
        <SomethingWrong />
      </>
   )
 }

//SomethingWrong.js
export default class SomethingWrong extends
Component {
  constructor(){
     // 未调用super,则会抛出错误
 }  
  render() {
    return (
      <div>
        <Child/>
      </div>
   )
 }
}

如果我们想让未出现错误的组件还能继续渲染,则可以使用 错误边界
错误边界 是一种 React 组件。
错误边界 可以捕获并打印发生在其子组件树任何位置的 JavaScript 错误,并且,它可以渲染出备用 UI。
错误边界 在渲染期间、生命周期方法和整个子组件树的构造函数中捕获错误。

 提示: 错误边界无法捕获以下场景中产生的错误:
1、事件处理
2、异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)

3、它自身抛出来的错误(并非它的子组件)

 错误边界_应用

1、 定义一个错误边界的组件
class 组件中定义了 static getDerivedStateFromError()componentDidCatch() 这两个生命周期方法中的任意一个(或两个)时,那么这个组件就变成一个错误边界的组件。

import React, { Component } from 'react'
export default class ErrorBoundary extends
Component {
    constructor() {
        super()
        this.state = { }
   }
    componentDidCatch(error, errorInfo) {
        // 捕获到子组件树当中发生的错误时调用
        this.setState({
          error: error,
          errorInfo: errorInfo
       })
        
     }
    render() {
        return (
           this.state.errorInfo ? <div>奥,糟糕!!发生了一些错误:
               错误信息如下:<br />
               {this.state.error && this.state.error.toString()}
            <br />
           {this.state.errorInfo.componentStack}
              
            </div> : this.props.children
       )
   }
}

错误边界的使用
 

//App.js
render() {
    return (
      <>
        <ContextTest />
         {/* 使用错误边界组件包裹的组件树,发生的错误都会被这个错误边界捕获 */}
        <ErrorBoundary>
          <SomethingWrong />
        </ErrorBoundary>
      </>
   )
 }

错误边界无法捕获的错误


 

 错误边界无法捕获的错误,比如事件处理,异步操作。可以使用原生js支持的一些方法去捕获。

 try/catch

onClick=()=>{
    try{
        //使用一个未定义的变量a,会报错
       console.log(a)
   }catch(e){
        console.log(e)
        this.setState({hasError:true})
   }
    
 }
  render() {
    return (
      <div>
        <button onClick={this.onClick}>点击</button>
       {this.state.hasError?<div>出现错误了</div>:null}
      </div>
   )
 }

window.onerror

window.onerror可以捕捉语法错误,也可以捕捉运行时错误,只要在当前window执行的Js脚本出错都会捕捉到。
 

window.onerror=function(err){
  console.log(err)
}

Refs & DOM

 Refs 提供了一种方式,允许我们访问DOM 元素。

<div ref={ref}></div>

创建 Refs
使用 React.createRef() 创建的。
通常将 Refs 分配给实例属性,以便可以在整个组件中引用它们。
 

constructor(props) {
    super(props);
    this.myRef = React.createRef();
 }

使用Refs
给对应的React 元素设置 ref 属性,则相当于使用 ref 去存储DOM 节点的引用。
 

render() {
    return <input ref={this.myRef} />;
 }

访问Refs
ref 被传递给 render 中的元素时,对该节点的引用可以在 ref current 属性中被访问。
 

componentDidMount(){
    const node = this.myRef.current;
    node.focus()
 }

提示:
React 会在组件挂载时给 current 属性传入 DOM 元素,并在组件卸载时传入 null 值。

ref 会在 componentDidMount componentDidUpdate
生命周期钩子触发前更新。

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

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

相关文章

深度学习自学笔记一:神经网络和深度学习

神经网络是一种模拟人脑神经元之间相互连接的计算模型&#xff0c;它由多个节点&#xff08;或称为神经元&#xff09;组成&#xff0c;并通过调整节点之间的连接权重来学习和处理数据。深度学习则是指利用深层次的神经网络进行学习和建模的机器学习方法。 假设有一个数据集&a…

电阻的读数

常见电阻的阻值一般有色环电阻和贴片电阻 &#xff0c;下面介绍两种电阻的阻值读法。 1、色标法&#xff1a; 技巧&#xff1a;四环电阻的的精度一般为银色和金色&#xff0c;如果一眼能可看到这两种颜色可以判断为第4环的精度读数 可见棕色为第1环&#xff0c;黑色第2环&…

Three.js后期处理简明教程

后期处理&#xff08;Post Processing&#xff09;通常是指对 2D 图像应用某种效果或滤镜。 在 THREE.js 中我们有一个包含一堆网格物体的场景。 我们将该场景渲染为 2D 图像。 通常&#xff0c;该图像会直接渲染到画布中并显示在浏览器中&#xff0c;但我们可以将其渲染到渲染…

AI写文章软件-怎么选择不同的AI写文章软件

在如今信息爆炸的时代&#xff0c;无论是学生、职场人士&#xff0c;还是创作者和企业家&#xff0c;写文章都是一项常见而又重要的任务。然而&#xff0c;随着科技的不断进步&#xff0c;AI写文章的软件也逐渐走进了人们的视野。 147GPT批量文章生成工具​www.147seo.com/post…

Java 基于微信小程序的学生选课系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 第一章&#xff1a; 简介第二章 技术栈第三章&#xff1a; 功能分析第四章 系统设计第五章 系统功…

Intel酷睿和AMD锐龙

Intel酷睿系列&#xff0c;主要分i3、i5、i7、i9 如&#xff1a;Intel 酷睿i5 10210U i5&#xff1a;品牌修饰符。 10&#xff1a;代次指示符。 210&#xff1a;sku编号。 常见后缀&#xff1a; G1-G7&#xff1a;集显等级。 U&#xff1a;低功耗。 H&#xff1a;标压版…

通俗易懂了解大语言模型LLM发展历程

1.大语言模型研究路程 NLP的发展阶段大致可以分为以下几个阶段&#xff1a; 词向量词嵌入embedding句向量和全文向量理解上下文超大模型与模型统一 1.1词向量 将自然语言的词使用向量表示&#xff0c;一般构造词语字典&#xff0c;然后使用one-hot表示。   例如2个单词&…

GeekRUN-7芯片跑分表

前两个字母是芯片简写&#xff0c;如麒麟&#xff0c;是QL&#xff0c;骁龙是XL&#xff0c;天玑是TJ&#xff0c;第一串数字是最高值&#xff0c;第二串是最低值&#xff0c;省电模式差不多这个水平。QL9K是麒麟9000&#xff0c;QL9S

aix360-gec

目录 分组条件期望&#xff08;GroupedCE&#xff09;解释程序创建虚拟环境导包加载数据集训练模型计算独立条件期望ICEplot_ice_explanation 计算分组条件期望 (GCE)plot_gce_explanation 记录一下学习过程&#xff0c;官方的代码在https://github.com/Trusted-AI/AIX360/tree…

High-Resolution Side Channels for Untrusted Operating Systems【ATC‘17】

目录 摘要引言贡献• 一个不受信任的操作系统的两个新的高分辨率侧通道来攻击受保护的应用程序&#xff1b;• 对 libjpeg 的显着改进攻击和针对 VC3 的新攻击&#xff1b;• 侧通道攻击对不受信任的操作系统的重要性增加。 系统模型背景Intel SGX页面错误通道时间限制空间限制…

微信小程序案例2-3:婚礼邀请函

文章目录 一、运行效果二、知识储备&#xff08;一&#xff09;导航栏设置1、导航栏的相关配置项2、利用导航栏组件2、在页面配置文件中对导航栏进行配置3、在全局配置文件中对导航栏进行配置 三、实现步骤 一、运行效果 “婚礼邀请函”微信小程序由4个页面组成&#xff0c;分别…

Springboot整合分页插件pagehelper

首先需要有一定的springbootmybatis的基础&#xff0c;才能使用顺畅 项目结构如下 引入依赖&#xff0c;springboot版本选的是2.7.16版本&#xff0c;jdk选的17&#xff0c; <!--分页插件--> <dependency><groupId>com.github.pagehelper</groupId><…

基于微信小程序的房屋租赁系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明用户微信小程序端的主要功能有&#xff1a;户主微信小程序端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文…

OceanBase 数据文件缩容实践

本文章介绍了OceanBase集群关于数据文件的缩容场景&#xff0c;并提供一种缩容方案予以参考。 作者&#xff1a;关炳文&#xff0c;爱可生 DBA 团队成员&#xff0c;负责数据库相关技术支持&#xff0c;一步两阶梯&#xff0c;兼具勤奋与慵懒。 爱可生开源社区出品&#xff0c;…

浅谈单元测试:测试和自动化中的利用

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程&#xff0c;刷完面试就稳了&#xff0c;你也可以当高薪软件测试工程师&#xff08;自动化测试&#xff09; 浅谈单元测试是一件棘手的事情。我很确定测试人员在某个时候会抱怨开发人员没有正确地进行单元测试&…

Idea中使用Service管理微服务

前言 如何在本地一键启动很多个微服务&#xff0c;下面介绍下IDEA开发工具中得Services管理管理功能 一、第一步 1、在IDEA中下栏bar中如果存在Services,请看第二步。 2、如果没有请按照以下步骤打开 View -> Tool Windows -> Services 二、第二步 刚创建好的窗口是空…

论文浅尝 | 基于知识增强的多行为对比推荐

笔记整理&#xff1a;吴飞跃&#xff0c;东南大学硕士&#xff0c;研究方向为推荐系统 链接&#xff1a;https://doi.org/10.1145/3539597.3570386 动机 在实际推荐场景中&#xff0c;用户和物品之间存在多种类型的交互行为&#xff0c;如在线购物平台上的点击、标记为喜欢和购…

【算法专题突破】二分查找 - 704. 二分查找(16)

目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 1. 题目解析 题目链接&#xff1a;704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; 题目非常简单&#xff0c;就是查找一个 target。 2. 算法原理 根据最基本的二分查找算法&#xff1a; 在一个…

Java代码随想录第一章:-数组理论基础,704. 二分查找,27. 移除元素 ,

一、数组理论基础 数组是存放在连续内存空间上的相同类型数据的集合。 数组可以方便的通过下标索引的方式获取到下标下对应的数据。 举一个字符数组的例子如图&#xff1a; 需要两点注意的是 数组下标都是从0开始的。数组内存空间的地址是连续的 正是因为数组的在内存空间…

Unity 发布WebGL平台,C#与JavaScript交互

发布H5平台&#xff0c;接入SDK&#xff0c;比如微信等&#xff0c;涉及到C#与JS的交互。 jslib&#xff08;JavaScript Library&#xff09;是Unity的一种机制&#xff0c;允许你在C#中通过JavaScript代码来执行一些操作。这是一种高级的技巧&#xff0c;主要用于一些特殊情况…