第三十七章 扩展知识点2

简介: 第三十七章 扩展知识点

第三十七章 扩展知识点 1:https://developer.aliyun.com/article/1409375

6、Fragment 和空标签(<> 和 </>)

React 中,Fragment 和空标签(<></>)都用于组合多个子元素,而不需要添加额外的 DOM 元素。这在避免不必要的 DOM 层次结构和提高性能方面非常有用。

使用 Fragment

要使用 Fragment,您需要从 react 包中导入它,然后将它作为包裹元素。以下是一个示例:

import React, { Fragment } from 'react';
function MyComponent() {
  return (
    <Fragment>
      <div>Element 1</div>
      <div>Element 2</div>
    </Fragment>
  );
}

在这个示例中,Element 1Element 2 将作为同级元素渲染,而不需要额外的包裹元素。

使用空标签

空标签(<></>)是 Fragment 的简写语法。它们的功能与 Fragment 相同,但更简洁。以下是一个使用空标签的示例:

import React from 'react';
function MyComponent() {
  return (
    <>
      <div>Element 1</div>
      <div>Element 2</div>
    </>
  );
}

在这个示例中,Element 1Element 2 也将作为同级元素渲染,而不需要额外的包裹元素。

请注意,虽然空标签更简洁,但它们不支持添加 key 属性。如果您需要在迭代中使用 Fragment 并添加 key 属性,您应该使用完整的 <Fragment> 标签。


7、Context

React 中,Context 是一种在组件树中传递数据的方法,而无需通过每个中间组件显式传递 props。这在处理跨越多个层次的全局数据(如主题、语言设置或用户信息)时非常有用。

(1)、创建 Context

首先,您需要创建一个 Context。通常,您会在应用程序的顶层创建一个 Context

import React from 'react';
const MyContext = React.createContext();
export default MyContext

(2)、使用Provider传递Context值

要在组件树中提供 Context 值,您需要使用 Provider 组件。Provider 接受一个 value 属性,该属性将作为 Context 的值传递给所有使用该 Context 的子组件。

import React, { Component } from 'react'
import B from './B'
import MyContext from './MyContext'
const {Provider} = MyContext
export default class Demo extends Component {
  render() {
    return (
      <div>
        <Provider value={{username:'tom',age:18}}>
          <B/>
        </Provider>
      </div>
    )
  }
}

(3)、在类式组件中使用static contextType接收Context值

在类组件中访问 Context 的方法是使用 static contextType。将 contextType 设置为您要访问的 Context,然后在组件中,您可以通过 this.context 访问 Context 的值。

import React, { Component } from 'react'
import MyContext from '../MyContext'
import C from '../C'
import D from '../D'
export default class B extends Component {
  static contextType = MyContext
  render() {
    console.log('我是B组件接收的context',this.context)
    return (
      <div>
        <h2>我是B组件{this.context.username+','+this.context.age}</h2>
        <C/>
        <D/>
      </div>
    )
  }
}

(4)、使用Customer在函数组件和类组件中接收Context值

在类组件和函数组件中,您可以使用 Context.Consumer 组件来访问 Context 值。Context.Consumer 接受一个函数作为子元素,该函数接收 Context 的值作为参数。

import MyContext from "../MyContext"
const {Consumer} = MyContext
export default function C () {
  return (
    <div>
      <Consumer>
        {value => {
          console.log('我是C组件接收的Context',value)
          return <h3>我是C组件{value.username+''+value.age}</h3>
        }}
      </Consumer>
    </div>
  )
}

(5)、使用useContext Hook在函数组件中接收Context值

要在组件中使用 Context 值,您可以使用 useContext HookuseContext 接受一个 Context 对象,并返回该 Context 的当前值。

import { useContext } from 'react'
import MyContext from '../MyContext'
export default function D () {
  const contextValue = useContext(MyContext)
  console.log('我是D组件接收的context',contextValue)
  return (
    <div>
      <h3>我是D组件</h3>
      <div>{contextValue.username+','+contextValue.age}</div>
    </div>
  )
}

请注意,虽然 Context 可以简化跨多个层次的数据传递,但在不需要的情况下过度使用 Context 可能会导致组件之间的不必要的耦合。因此,建议仅在确实需要全局数据时使用 Context ,在应用开发中一般不用Context, 一般都用它的封装react插件

8、组件优化

Component的2个问题
  1. 只要执行setState(),即使不改变状态数据, 组件也会重新render() ==> 效率低
  2. 只当前组件重新render(), 就会自动重新render子组件,纵使子组件没有用到父组件的任何数据 ==> 效率低
效率高的做法

只有当组件的state或props数据发生改变时才重新render()

原因

Component中的shouldComponentUpdate()总是返回true

解决
办法1: 
  重写shouldComponentUpdate()方法
  比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
办法2:  
  使用PureComponent
  PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
  注意: 
    只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false  
    不要直接修改state数据, 而是要产生新数据
项目中一般使用PureComponent来优化
如何理解pureComponent

我们首先需要了解React组件的基本概念。在React中,有两种类型的组件:函数组件和类组件。PureComponent是类组件的一种特殊类型,它可以帮助我们优化性能。

PureComponentReact提供的一个基类,它继承自React.Component。与普通的Component不同,PureComponent实现了一个浅比较(shallow comparison)的shouldComponentUpdate方法。这意味着,当组件的propsstate发生变化时,PureComponent会对新旧propsstate进行浅比较,如果它们相等,那么组件就不会重新渲染。这可以避免不必要的渲染,从而提高性能。

要使用PureComponent,只需将组件的基类从React.Component更改为React.PureComponent。例如:

import React from 'react';
class MyComponent extends React.PureComponent {
  // ...
}

需要注意的是,PureComponent的浅比较可能会导致一些问题。例如,当组件的propsstate包含嵌套对象时,浅比较可能无法检测到嵌套对象的变化。因此,在使用PureComponent时,需要确保组件的propsstate是不可变的(immutable)。

总之,PureComponent是一种特殊的React类组件,它通过实现浅比较的shouldComponentUpdate方法来避免不必要的渲染,从而提高性能。在使用PureComponent时,需要确保组件的propsstate是不可变的

使用shouldComponentUpdate进行自定义优化

如果PureComponentReact.memo的浅比较不足以满足需求,可以在类组件中实现自定义的shouldComponentUpdate方法。这允许您根据特定条件决定组件是否应该重新渲染。例如:

  class MyComponent extends React.Component {
    shouldComponentUpdate(nextProps, nextState) {
      // 自定义比较逻辑
      return nextProps.someProp !== this.props.someProp;
    }
    // ...
  }

React.memoReact库中的一个高阶组件(Higher-Order Component,简称HOC),它用于优化函数组件的性能。React.memo的作用类似于类组件中的PureComponent,它通过对组件的props进行浅比较(shallow comparison)来避免不必要的重新渲染。

当使用React.memo包装一个函数组件时,只有当组件的props发生变化时,组件才会重新渲染。这可以帮助我们减少不必要的渲染,从而提高性能。例如:

import React from 'react';
const MyComponent = React.memo(function MyComponent(props) {
  // ...
});

需要注意的是,React.memo的浅比较可能会导致一些问题。例如,当组件的props包含嵌套对象时,浅比较可能无法检测到嵌套对象的变化


9、render props

如何向组件内部动态传入带内容的结构(标签)?
Vue中: 
  使用slot技术, 也就是通过组件标签体传入结构  <A><B/></A>
React中:
  使用children props: 通过组件标签体传入结构
  使用render props: 通过组件标签属性传入结构,而且可以携带数据,一般用render函数属性
children props
<A>
  <B>xxxx</B>
</A>
{this.props.children}
问题: 如果B组件需要A组件内的数据, ==> 做不到 

标签体是一种React模式,它允许您将一个或多个React元素作为组件的子元素传递,并在组件中渲染这些元素。这些子元素可以是任何有效的React元素,包括其他组件。例如:

function MyComponent(props) {
  return (
    <div>
      {props.children}
    </div>
  );
}
function App() {
  return (
    <MyComponent>
      <div>Child 1</div>
      <div>Child 2</div>
    </MyComponent>
  );
}

在这个例子中,MyComponent接受一个名为childrenprop,该prop是一个React元素或一组React元素。在MyComponent中,我们使用props.children来渲染这些子元素。在App组件中,我们将两个<div>元素作为MyComponent的子元素传递。这些元素将被渲染为MyComponent的子元素。

render props
<A render={(data) => <C data={data}></C>}></A>
A组件: {this.props.render(内部state数据)}
C组件: 读取A组件传入的数据显示 {this.props.data} 

render props是另一种React模式,它允许您将一个函数作为prop传递给组件,并在组件中调用该函数以渲染子元素。这个函数通常称为renderchildren。例如:

function MyComponent(props) {
  const { render } = props;
  const data = { /* some data */ };
  return (
    <div>
      {render(data)}
    </div>
  );
}
function App() {
  return (
    <MyComponent
      render={(data) => (
        <div>
          {/* render something based on the data */}
        </div>
      )}
    />
  );
}

在这个例子中,MyComponent接受一个名为renderprop,该prop是一个函数。在MyComponent中,我们调用render函数并将数据作为参数传递。render函数返回一个React元素,该元素用于渲染MyComponent的子元素。


总之,标签体和render props是两种不同的React模式,它们的作用和用法也有所不同。标签体用于将React元素作为组件的子元素传递,而render props用于将函数作为prop传递,并在组件中调用该函数以渲染子元素。这两种模式都可以用于实现组件的可重用性和灵活性


10、 错误边界

理解:

错误边界(Error boundary):用来捕获后代组件错误,渲染出备用页面

特点:

只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误

使用方式:getDerivedStateFromError配合componentDidCatch
// 生命周期函数,一旦后台组件报错,就会触发
static getDerivedStateFromError(error) {
    console.log(error);
    // 在render之前触发
    // 返回新的state
    return {
        hasError: true,
    };
}
componentDidCatch(error, info) {
    // 统计页面的错误。发送请求发送到后台去
    console.log(error, info);
}

对于React应用程序中的错误处理,可以使用错误边界来捕获和处理组件中的错误。错误边界是一种React组件,它可以捕获其子组件中的错误,并显示备用UI而不是崩溃的UI。以下是一个简单的错误边界组件的示例:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }
  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.error(error, errorInfo);
  }
  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>服务器异常,请稍后在试.</h1>;
    }
    return this.props.children; 
  }
}

在这个例子中,ErrorBoundary是一个错误边界组件。它通过getDerivedStateFromErrorcomponentDidCatch方法来捕获子组件中的错误,并在发生错误时显示备用UI

getDerivedStateFromError方法返回一个对象,该对象将更新组件的状态以显示备用UIcomponentDidCatch方法可以用于记录错误或将错误发送到错误报告服务。

要使用错误边界,只需将其包装在可能会发生错误的组件周围即可。例如:

<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>

在这个例子中,MyComponent是可能会发生错误的组件。通过将MyComponent包装在ErrorBoundary中,我们可以捕获并处理MyComponent中的错误。

案例:我们在render里面写一段错误代码,render属于生命周期

import React, { Component } from 'react'
export default class Demo extends Component {
  state = {users:'users'}
  render() {
    return (
      <div>
        我是Demo组件
        {
          this.state.users.map((user)=>{
            return <h1>{user.name}</h1>
          })
        }
      </div>
    )
  }
}

查看效果:


11、组件通信方式总结

组件间的关系:
  • 父子组件
  • 兄弟组件(非嵌套组件)
  • 祖孙组件(跨级组件)
几种通信方式:
  1.props:
    (1).children props
    (2).render props
  2.消息订阅-发布:
    pubs-sub、event等等
  3.集中式管理:
    redux、dva等等
  4.conText:
    生产者-消费者模式
比较好的搭配方式:
  父子组件:props
  兄弟组件:消息订阅-发布、集中式管理
  祖孙组件(跨级组件):消息订阅-发布、集中式管理、conText(开发用的少,封装插件用的多)


相关文章
|
存储 Kubernetes 网络协议
Kubernetes 集群部署 NFS-Subdir-External-Provisioner 存储插件
Kubernetes 对 Pod 进行调度时,以当时集群中各节点的可用资源作为主要依据,自动选择某一个可用的节点,并将 Pod 分配到该节点上。在这种情况下,Pod 中容器数据的持久化如果存储在所在节点的磁盘上,就会产生不可预知的问题,例如,当 Pod 出现故障,Kubernetes 重新调度之后,Pod 所在的新节点上,并不存在上一次 Pod 运行时所在节点上的数
9071 3
Kubernetes 集群部署 NFS-Subdir-External-Provisioner 存储插件
|
安全 Linux 网络安全
【工具使用】几款优秀的SSH连接客户端软件工具推荐FinalShell、Xshell、MobaXterm、OpenSSH、PUTTY、Terminus、mRemoteNG、Terminals等
【工具使用】几款优秀的SSH连接客户端软件工具推荐FinalShell、Xshell、MobaXterm、OpenSSH、PUTTY、Terminus、mRemoteNG、Terminals等
134340 0
|
14天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
28546 100
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
4天前
|
应用服务中间件 API 网络安全
3分钟汉化OpenClaw,使用Docker快速部署启动OpenClaw(Clawdbot)教程
2026年全新推出的OpenClaw汉化版,是基于Claude API开发的智能对话系统本土化优化版本,解决了原版英文界面的使用壁垒,实现了界面、文档、指令的全中文适配。该版本采用Docker容器化部署方案,开箱即用,支持Linux、macOS、Windows全平台运行,适配个人、企业、生产等多种使用场景,同时具备灵活的配置选项和强大的扩展能力。本文将从项目简介、部署前准备、快速部署、详细配置、问题排查、监控维护等方面,提供完整的部署与使用指南,文中包含实操代码命令,确保不同技术水平的用户都能快速落地使用。
3158 0
|
10天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
5523 15
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
8天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
4007 8
|
11天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
5138 17
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
|
11天前
|
存储 人工智能 机器人
OpenClaw是什么?阿里云OpenClaw(原Clawdbot/Moltbot)一键部署官方教程参考
OpenClaw是什么?OpenClaw(原Clawdbot/Moltbot)是一款实用的个人AI助理,能够24小时响应指令并执行任务,如处理文件、查询信息、自动化协同等。阿里云推出的OpenClaw一键部署方案,简化了复杂配置流程,用户无需专业技术储备,即可快速在轻量应用服务器上启用该服务,打造专属AI助理。本文将详细拆解部署全流程、进阶功能配置及常见问题解决方案,确保不改变原意且无营销表述。
5593 5
|
13天前
|
人工智能 JavaScript 应用服务中间件
零门槛部署本地AI助手:Windows系统Moltbot(Clawdbot)保姆级教程
Moltbot(原Clawdbot)是一款功能全面的智能体AI助手,不仅能通过聊天互动响应需求,还具备“动手”和“跑腿”能力——“手”可读写本地文件、执行代码、操控命令行,“脚”能联网搜索、访问网页并分析内容,“大脑”则可接入Qwen、OpenAI等云端API,或利用本地GPU运行模型。本教程专为Windows系统用户打造,从环境搭建到问题排查,详细拆解全流程,即使无技术基础也能顺利部署本地AI助理。
7469 16