React组件化开发

news2024/12/26 11:13:48

1.组件的定义方式

  • 函数组件Functional Component
  • 类组件Class Component

2.类组件

export class Profile extends Component {
  render() {
    console.log(this.context);
    return (
      <div>Profile</div>
    )
  }
}
  • 组件的名称是大写字符开头(无论类组件还是函数组件)
  • 类组件需要继承自 React.Component
  • 类组件必须实现render函数
  • constructor是可选的,我们通常在constructor中初始化一些数据
render函数的返回值

当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回以下类型之一:

  • React 元素:通常通过 JSX 创建
  • 数组或 fragments:使得 render 方法可以返回多个元素
  • Portals:可以渲染子节点到不同的 DOM 子树中
  • 字符串或数值类型:它们在 DOM 中会被渲染为文本节点
  • 布尔类型或 null:什么都不渲染

3.函数组件

函数组件是使用function来进行定义的函数,只是这个函数会返回和类组件中render函数返回一样的内容。

函数组件有自己的特点:

  • 没有生命周期,也会被更新并挂载,但是没有生命周期函数
  • this关键字不能指向组件实例(因为没有组件实例)
  • 没有内部状态(state)

4.生命周期

React内部为了告诉我们当前处于哪些阶段,会对我们组件内部实现的某些函数进行回调,这些函数就是生命周期函数:

  • 实现componentDidMount函数:组件已经挂载到DOM上时,就会回调
  • 实现componentDidUpdate函数:组件已经发生了更新时,就会回调
  • 实现componentWillUnmount函数:组件即将被移除时,就会回调
不常用的生命周期
  • getDerivedStateFromProps:state 的值在任何时候都依赖于 props时使用;该方法返回一个对象来更新state
  • getSnapshotBeforeUpdate:在React更新DOM之前回调的一个函数,可以获取DOM更新前的一些信息(比如说滚动位置)
  • shouldComponentUpdate:可进行state、props、context进行新旧对比,返回true或false进行是否更新组件

5.组件之间的通信

  • 父组件通过 属性=值 的形式来传递给子组件数据
  • 子组件通过 props 参数获取父组件传递过来的数据

父组件:

import React from "react"
// import HelloWorld from "./Components/HelloWorld"
import TabControl from './Components/父子组件通信案例'
// import NavBar from './Components/实现插槽一'
// import NavBar from './Components/实现插槽二'
// import TabControl from './Components/作用域插槽'
// import AppHome from "./Components/非父子组件通信-context/AppHome";

class App extends React.Component {
  constructor() {
    super()
    console.log("hello react");
    this.state = {
      message: "hello react",
      isShow: true,
      titles: ['流行', '新款', '精选'],
      curIndex: 0
    }
  }
  changeText() {
    this.setState({
      message: 'hello  hgf'
    })
  }
  switchText() {
    this.setState({
      isShow: !this.state.isShow
    })
  }

  switchTab(curIndex){
    this.setState({curIndex})
  }

  render() {
    const { titles, curIndex } = this.state
    return (
      <div>
        <TabControl titles={titles} changeTab={(curIndex) => this.switchTab(curIndex)} />
        {/* <h2>{titles[curIndex]}</h2> */}
        {/* <h2>{message}</h2> */}
        {/* <button onClick={e => this.switchText()}>切换</button> */}
        {/* {isShow && <HelloWorld/>} */}
        {/* <button onClick={e => this.changeText()}>修改文本</button> */}
        {/* 插槽实现1 */}
        {/* <NavBar>
          <button>左边</button>
          <h2>中间部分</h2>
          <button>右边</button>
        </NavBar> */}
        {/* 插槽实现二 */}
        {/* <NavBar leftSlot={<button>左按钮</button>} centerSlot={<h2>插槽实现二</h2>} rightSlot={<button>右按钮</button>} /> */}
        {/* 作用域插槽 */}
        {/* <TabControl titles={titles} itemTypes={(item) => <button>{item}</button>} changeTab={(curIndex) => this.switchTab(curIndex)} />
        <h2>{titles[curIndex]}</h2> */}
        {/* 非父子组件通信 */}
        {/* <AppHome /> */}
      </div>
    )
  }

  componentDidMount() {
    console.log("component Mount")
  }

  componentDidUpdate() {
    console.log("component Update");
  }
}

export default App

子组件:

import React, { Component } from 'react'
import "./tab-control.css"

export class index extends Component {
  constructor() {
    super()
    this.state = {
      curIndex: 0
    }
  }
  changeCurIndex(index) {
    this.setState({curIndex: index})
    this.props.changeTab(index)
  }
  render() {
    const {titles} = this.props
    const {curIndex} = this.state
    return (
      <div>
        <div className='tab-control'>
        {
          titles.map((item, index) => {
            return (
              <div className={`item ${index === curIndex ? 'active':''}`} key={item} onClick={e => this.changeCurIndex(index)}>
                <span className='text'>{item}</span>
              </div>
            )
          })
        }
        </div>

      </div>
    )
  }
}

export default index

6.React中实现插槽

React对于这种需要插槽的情况非常灵活,有两种方案可以实现:

  • 组件的children子元素
  • props属性传递React元素
方式一:

import React, { Component } from 'react'
import "./style.css"

export class index extends Component {
  render() {
    const {children} = this.props

    return (
      <div className='nav-bar'>
        <div className='left'>
          {children[0]}
        </div>
        <div className='center'>
        {children[1]}
        </div>
        <div className='right'>
        {children[2]}
        </div>
      </div>
    )
  }
}

// index.propTypes = {
//   children: PropTypes.element
// }

export default index
方式二:

import React, { Component } from 'react'
import "./style.css"

export class index extends Component {
  render() {
    const {leftSlot, centerSlot, rightSlot} = this.props

    return (
      <div className='nav-bar'>
        <div className='left'>
          {leftSlot}
        </div>
        <div className='center'>
        {centerSlot}
        </div>
        <div className='right'>
        {rightSlot}
        </div>
      </div>
    )
  }
}

// index.propTypes = {
//   children: PropTypes.element
// }

export default index

7.context应用场景

非父子组件数据的共享:

对于有一些场景:比如一些数据需要在多个组件中进行共享(地区偏好、UI主题、用户登录状态、用户信息等)

  • React提供了一个API:Context
  • Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props
  • Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言
Context相关API:
React.createContext
  • 创建一个需要共享的Context对象

  • 如果一个组件订阅了Context,那么这个组件会从离自身最近的那个匹配的 Provider 中读取到当前的context值
  • defaultValue是组件在顶层查找过程中没有找到对应的Provider,那么就使用默认值

Context.Provider
  • 每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化
  • Provider 接收一个 value 属性,传递给消费组件
  • 一个 Provider 可以和多个消费组件有对应关系
  • 多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据
  • 当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染

创建context
import React from "react";

const ThemeContext = React.createContext({nickname: 'curry', work: '前端'})

export default ThemeContext
import React from "react";

const UserContext = React.createContext()

export default UserContext
 提供值
import React, { Component } from 'react'
import ThemeContext from './context/theme-context'
import UserContext from './context/user-context'
import Home from './context/Home'
import Profile from './context/Profile'

export class AppHome extends Component {
  render() {
    return (
      <div>
        App
        <UserContext.Provider value={{name: 'hgf', age: 23}}>
          <ThemeContext.Provider value={{color: 'red', size: '30px'}}>
            <Home />
          </ThemeContext.Provider>
        </UserContext.Provider>
        <Profile />
      </div>
    )
  }
}

export default AppHome
获取和使用方式 
import React, { Component } from 'react'
import ThemeContext from './theme-context'

export class Profile extends Component {
  render() {
    console.log(this.context);
    return (
      <div>Profile</div>
    )
  }
}

Profile.contextType = ThemeContext

export default Profile
import React, { Component } from 'react'
import ThemeContext from './theme-context';
import UserContext from './user-context';

export class HomeInfo extends Component {
  render() {
    console.log(this.context);
    return (
      <div>
        HomeInfo
        <UserContext.Consumer>
          {
            value => {
              return <h2>InfoUser: {value.age}</h2>
            }
          }
        </UserContext.Consumer>
        </div>
    )
  }
}

HomeInfo.contextType = ThemeContext

export default HomeInfo

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

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

相关文章

ElementUI之登录与注册

目录 一.前言 二.ElementUI的简介 三.登录注册前端界面的开发 三.vue axios前后端交互--- Get请求 四.vue axios前后端交互--- Post请求 五.跨域问题 一.前言 这一篇的知识点在前面两篇的博客中就已经详细详解啦&#xff0c;包括如何环境搭建和如何建一个spa项目等等知识…

【二叉树魔法:链式结构与递归的纠缠】

本章重点 二叉树的链式存储二叉树链式结构的实现二叉树的遍历二叉树的节点个数以及高度二叉树的创建和销毁二叉树的优先遍历和广度优先遍历二叉树基础oj练习 1.二叉树的链式存储 二叉树的链式存储结构是指&#xff0c;用链表来表示一棵二叉树&#xff0c;即用链来指示元素的逻辑…

GitHub Copilot Chat

9月21日&#xff0c;GitHub在官网宣布&#xff0c;所有个人开发者可以使用GitHub Copilot Chat。用户通过文本问答方式就能生成、检查、分析各种代码。 据悉&#xff0c;GitHub Copilot Chat是基于OpenAI的GPT-4模型打造而成&#xff0c;整体使用方法与ChatGPT类似。例如&…

帆软BI开发-Day2-趋势图的多种变形

前言&#xff1a; 在BI数据展示中&#xff0c;条形图、趋势图无疑是使用场景非常多的两种图形。与条形图不同的是&#xff0c;趋势图更能反馈出一定的客观规律和未来的趋势走向&#xff0c;因此用于作为预警和判异的业务场景&#xff0c;但实际业务场景的趋势图可没你想的那么简…

代码随想录算法训练营 动态规划part14

一、最长公共子序列 1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int longestCommonSubsequence(String s1, String s2) {int n s1.length(), m s2.length();char[] cs1 s1.toCharArray(), cs2 s2.toCharArray();int[][] f n…

精华回顾:Web3 前沿创新者在 DESTINATION MOON 共话未来

9 月 17 日&#xff0c;由 TinTinLand 主办的「DESTINATION MOON: Web3 Dev Summit Shanghai 2023」线下活动在上海黄浦如约而至。 本次 DESTINATION MOON 活动作为 2023 上海区块链国际周的 Side Event&#xff0c;设立了 4 场主题演讲与 3 个圆桌讨论&#xff0c;聚集了诸多…

[python 刷题] 42 Trapping Rain Water

[python 刷题] 42 Trapping Rain Water 题目&#xff1a; Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining. 这题的前置我觉得至少还是得做过 11 Container With Most Wat…

神经辐射场(Neural Radiance Field,NeRF)的简单介绍

参考文章&#xff1a;https://arxiv.org/abs/2210.00379 1. 概述 神经辐射场&#xff08;NeRF&#xff09;模型是一种新视图合成方法&#xff0c;它使用体积网格渲染&#xff0c;通过MLP进行隐式神经场景表达&#xff0c;以学习3D场景的几何和照明。   应用&#xff1a;照片…

浅谈双指针算法

目录 算法概述 案例分析 1、删除有序数组中的重复项 2、环形链表 3、盛最多水的容器 4、有效三角形的个数 5、三数之和 6、1089. 复写零 内容总结 算法概述 双指针指的是在遍历元素的过程中&#xff0c;不是使用单个指针进行访问&#xff0c;而是使用两个指针进行访问…

Linux启动过程详解 Xmind导图笔记

参考大佬博客&#xff1a; 简要描述linux系统从开机到登陆界面的启动过程 Linux启动过程详解 Bootloader详解 来源&#xff1a;从BIOS开始画图了解Linux启动过程——老杨Linux

WBS字典解释和举例

定义 WBS词典通常包括&#xff1a;编码、工作包描述&#xff08;内容&#xff09;、成本预算、时间安排、质量标准或要求、责任人或部门或外部单位&#xff08;委托项目&#xff09;、资源配置情况、其他属性等。 实例

Qt5开发及实例V2.0-第十五章-Qt单元测试框架

Qt5开发及实例V2.0-第十五章-Qt单元测试框架 第15章 Qt 5单元测试框架15.1 QTestLib框架15.2 简单的Qt单元测试15.3 数据驱动测试15.4 简单性能测试 本章相关例程源码下载1.Qt5开发及实例_CH1501.rar 下载2.Qt5开发及实例_CH1502.rar 下载3.Qt5开发及实例_CH1503.rar 下载4.Qt5…

【李宏毅 | 深度学习】自注意力机制(Self-attention)

这里写目录标题 引言Sequence LabelingSelf-attention矩阵乘法Muti-head Self-attention&#xff08;多头注意力机制&#xff09; 引言 以往我们遇到的深度学习问题中&#xff0c;对于神经网络的输入一般都是一个向量&#xff0c;输出可能是一个类别。如果增加输入的复杂度&am…

基于open CV实现YOLOv3复现_预测阶段和后处理阶段

基于open CV实现YOLOv3复现_预测阶段和后处理阶段 1.导入所需的库&#xff1a;2.对输入的图像进行resize3.将图像输入yolov3的网络中进行预测&#xff0c;对三个特征层进行解码。4.非极大值抑制来去除多余的预测框完整代码 当训练好了模型后&#xff0c;用训练好的权重文件进行…

tftpd文件传输工具的学习记录

1.目的&#xff1a;在SOC板上的linux系统和本地电脑的windows系统进行文件的传输。 2.在windows中安装tftp服务器,其下载的文件如下&#xff1a; 链接: https://pan.baidu.com/s/1YN5WxcjqCJLHTtjhUtKbjg 提取码: 3cg9 3.打开软件&#xff0c;在当前目录下选择windows传输的…

TCP协议中常见的问题

文章目录 TCP协议中常见的问题谈一谈对OSI七层模型和TCP/IP四层模型的理解&#xff1f;谈谈TCP协议的3次握手过程&#xff1f;TCP协议为什么要3次握手&#xff1f;2次&#xff0c;4次不行吗&#xff1f;谈谈TCP协议的四次挥手过程&#xff1f;什么是流量控制&#xff1f;什么是…

报错处理:Error: Redis server is running but Redis CLI cannot connect

嗨&#xff0c;读者朋友们&#xff01;今天我来跟大家分享一个我在运维过程中遇到的一个关于Linux上运行Redis服务时的报错及解决方法。 报错信息如下&#xff1a; Error: Redis server is running but Redis CLI cannot connect 这个报错信息表明Redis服务器已经运行&#xff…

stm32之GPIO库函数点灯分析

stm32官方为了方便开发者&#xff0c;利用CubeMX 生成HAL库有关的C代码。HAL库就是硬件抽象层(hardware abstraction layer)&#xff0c;生成一系列的函数帮助我们快速生成工程&#xff0c;脱离复杂的寄存器配置。stm32相对于51来功能强大&#xff0c;但是寄存器的数量也不是一…

动手吧,vue数字动画

数字动画&#xff0c;有数字的地方都能用上&#xff0c;拿去吧&#xff01; 效果&#xff1a; 1、template部分 <template><div class"v-count-up">{{ dispVlaue }}</div> </template> 2、js部分 export default {data() {return {timer…

版本动态 | SolidUI 0.3.0 版本发布

文章目录 背景发版清单功能部署 示例html生成模型选择数据源 详细指引贡献者如何成为贡献者 背景 随着文本生成图像的语言模型兴起&#xff0c;SolidUI想帮人们快速构建可视化工具&#xff0c;可视化内容包括2D,3D,3D场景&#xff0c;从而快速构三维数据演示场景。SolidUI 是一…