黑马React18: 基础Part 1

黑马React: 基础1

Date: November 15, 2023
Sum: React介绍、JSX、事件绑定、组件、useState、B站评论


React介绍

概念: React由Meta公司研发,是一个用于 构建Web和原生交互界面的库

Untitled

优势: 1-组件化的开发方式 2-优秀的性能 3-丰富的生态 4-跨平台开发




开发环境搭建

使用create-react-app快速搭建开发环境

create-react-app是一个快速 创建React开发环境的工具,底层由Webpack构建,封装了配置细节,开箱即用

执行命令

npx create-react-app react-basic
  1. npx Node.js工具命令,查找并执行后续的包命令
  2. create-react-app 核心包(固定写法),用于创建React项目
  3. react-basic React项目的名称(可以自定义)

之后切入到文件夹下, 使用 npm start启动项目

Untitled

创建React项目的更多方式: https://zh-hans.react.dev/learn/start-a-new-react-project

工作方式:

Untitled

理解:

index.js项目入口
App.js项目的根组件
index.htmlhtml文件

项目的根组件以React组件的方式渲染到index.html中

  • Code:

    index.js 简化后的内容

    // 项目的入口 从这里开始
    
    // React必要的两个核心包
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    
    // 导入项目的根组件
    import App from './App';
    
    // 把App根组件渲染到id为root的dom节点上
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <App />
    );
    



JSX基础-概念和本质

什么是JSX

**概念:**JSX是JavaScript和XML(HTML)的缩写,表示在JS代码中编写HTML模版结构,它是React中编写UI模版的方式

Untitled

优势:

  1. HTML的声明式模版写法 2. JS的可编程能力

JSX的本质

JSX并不是标准的JS语法,它是JS的语法扩展,浏览器本身不能识别,需要通过解析工具做解析之后才能在浏览器中运行

Untitled



JSX基础-高频场景

JSX中使用JS表达式

在JSX中可以通过 大括号语法{} 识别 JavaScript中的表达式,比如常见的变量、函数调用、方法调用等等

  1. 使用引号传递字符串
  2. 使用JavaScript变量
  3. 函数调用和方法调用
  4. 使用JavaScript对象

注意:if语句、switch语句、变量声明属于语句,不是表达式,不能出现在{}中

案例:

  • Code:

    // 项目的根组件
    // App -> index.js -> public/index.html(root)
    
    const count = 100
    
    function getName() {
      return 'jack'
    }
    
    function App() {
      return (
        <div className="App">
          this is App
          {/* 使用引号传递字符串 */}
          {'this is message'}
          {/* 识别js变量 */}
          {count}
          {/* 函数调用 */}
          {getName()}
          {/* 方法调用 */}
          {new Date().getDate()}
          {/* 使用js对象 */}
          <div style={{ color: 'red'}}>this is div</div>
        </div>
      )
    }
    
    export default App
    

效果:

Untitled


JSX中实现列表渲染

**语法:**在JSX中可以使用原生JS中的map方法遍历渲染列表

Untitled

案例:

const list = [
  { id: 1001, name: 'Vue'},
  { id: 1002, name: 'React'},
  { id: 1003, name: 'Angular'}
]

function App() {
  return (
    <div className="App">
      this is App
      {/* 渲染列表 */}
      <ul>
        {/* { list.map(item => <li>Vue</li>) } */}
        { list.map(item => <li key={item.id}>{ item.name }</li>) }
      </ul>
    </div>
  )
}

export default App

效果:

Untitled

要点:

1-key值绑定

作用: 提升性能

方式: 每一项要加上一个独一无二的key值


JSX中实现条件渲染

Untitled

**语法:**在React中,可以通过逻辑与运算符&&、三元表达式(?:)实现基础的条件渲染

案例:

const isLogin = true

function App() {
  return (
    <div className="App">
      {/* 逻辑与 && */}
      { isLogin && <span>this is span</span>}

      {/* 三目运算符 */}
      { isLogin ? <span>this is span</span> : <div>this is div</div>}

      {/* 逻辑或 || */}
      { isLogin || <span>this is span</span>}
    </div>
  )
}

export default App

效果:

this is spanthis is span


JSX中实现复杂条件渲染

Untitled

需求:列表中需要根据文章状态适配三种情况,单图,三图,和无图三种模式

解决方案:自定义函数 + if判断语句

案例:

// 定义文章类型
const articleType = 3  // 0 1 3

// 定义核心函数(根据文章类型返回不同的JSX模版)

function getArticleTem () {
  if (articleType === 0) {
    return <div>我是无图文章</div>
  } else if (articleType === 1) {
    return <div>我是单图模式</div>
  } else {
    return <div>我是三图模式</div>
  }
}

function App () {
  return (
    <div className="App">
      {/* 调用函数渲染不同的模版 */}
      {getArticleTem()}
    </div>
  )
}

export default App

效果:

我是三图模式




React中的事件绑定

React 基础事件绑定

**语法:**on + 事件名称 = { 事件处理程序 },整体上遵循驼峰命名法

Code:

function App() {
  const handleClick = () => {
    console.log('button被点击了');
  }
  return (
    <div className="App">
      <button onClick={handleClick}>Click</button>
    </div>
  )
}

export default App

Res:

Untitled


使用事件对象参数

语法:在事件回调函数中设置形参e

Code:


function App() {
  const handleClick = (e) => {
    console.log('button被点击了', e);
  }
  return (
    <div className="App">
      <button onClick={handleClick}>Click</button>
    </div>
  )
}

export default App

Res:

Untitled


传递自定义参数

语法:事件绑定的位置改成箭头函数的写法,在执行clickHandler实际处理业务函数的时候传递实参

Code:

function App() {
  const handleClick = (name) => {
    console.log('button被点击了', name);
  }
  return (
    <div className="App">
      <button onClick={() => handleClick('jack')}>Click</button>
    </div>
  )
}

export default App

Res:

Untitled

注意:不能直接写函数调用,这里事件绑定需要一个函数引用


同时传递事件对象和自定义参数

语法:在事件绑定的位置传递事件实参e和自定义参数,clickHandler中声明形参,注意顺序对应

Code:

function App() {
  const handleClick = (name, e) => {
    console.log('button被点击了', name, e);
  }
  return (
    <div className="App">
      <button onClick={(e) => handleClick('jack', e)}>Click</button>
    </div>
  )
}

export default App

Res:

Untitled




React中的组件

组件是什么

概念:一个组件就是用户界面的一部分,它可以有自己的逻辑和外观,组件之间可以互相嵌套,也可以复用多次

Untitled

组件化开发可以让开发者像搭积木一样构建一个完整的庞大的应用



React组件

在React中,一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图UI, 渲染组件只需要把组件当成标签书写即可

Code:

function Button() {
  return <button>click me!</button> 
}

function App() {
  return (
    <div className="App">
      {/* 自闭合 */}
      <Button />
      {/* 成对标签 */}
      <Button></Button>
    </div>
  )
}

export default App

Res:

Untitled




useState

useState基础使用

概念:

useState 是一个 React Hook(函数),它允许我们向组件添加一个状态变量, 从而控制影响组件的渲染结果

Untitled

本质:和普通变量不同的是,状态变量一旦发生变化组件的视图UI也会跟着变化(数据驱动视图)

const [count, setCount] = useState(0)

1- useState是一个函数, 返回值是一个数组

2-数组中的第一个参数是状态变量, 第二个参数是set函数用来修改状态变量

3-useState的参数将作为count的初始值

Case:

func: 点击按钮, 数值不断增加

Code:

import { useState } from "react"

function App() {
  // 1. 调用 useState 添加一个状态变量
  // count 状态变量
  // setCount 修改状态变量的方法
  const [count, setCount] = useState(0)

  // 2. 点击事件
  const handleClick = () => {
    setCount(count + 1)
  }
  return (
    <div className="App">
      <button onClick={ () => handleClick()}>Add-{count}</button>
    </div>
  )
}

export default App

Res:

Untitled



修改状态的规则

状态不可变

在React中,状态被认为是只读的,我们应该始终替换它而不是修改它,直接修改状态不能引发视图更新

Untitled

Untitled

Case:

Code:

import { useState } from "react"

function App() {
  // 1. 调用 useState 添加一个状态变量
  // count 状态变量
  // setCount 修改状态变量的方法
  const [count, setCount] = useState(0)

  // 2. 点击事件
  const handleClick = () => {
    setCount(count + 1)
  }
  return (
    <div className="App">
      <button onClick={ () => handleClick()}>Add-{count}</button>
    </div>
  )
}

export default App


修改对象状态

规则:对于对象类型的状态变量,应该始终传给set方法一个全新的对象来进行修改

直接修改原对象,不引发视图变化

Untitled

调用set传入新对象用于修改

Untitled

理解: 这里先用展开运算符做个拷贝, 然后再用后面重复属性进行替换即可.

Case:

func: 点击按变换名字

Code:

import { useState } from "react"

function App() {

  const [form, setForm] = useState({ name: 'jack' })

  const handleClick = () => {
    setForm({
      ...form,
      name: 'rose'
    })
  }
  return (
    <div className="App">
      <button onClick={ () => handleClick()}>Add-{form.name}</button>
    </div>
  )
}

export default App

Res:

Untitled

复习知识点:

1-…展开匀速符: 深浅拷贝问题

展开运算符使用的对象如果只是针对简单的一级基础数据,就是深拷贝;
展开运算符使用的对象内容包含二级或更多的复杂的数据,那就是浅拷贝;




组件的样式处理

组件基础样式方案

React组件基础的样式控制有俩种方式

  1. 行内样式(不推荐)

Untitled

  1. class类名控制

Untitled

Case:

Code:

index.js

import './css/index.css'

const style = {
  color: 'red',
  fontSize: '20px'
}

function App() {
  return (
    <div className="App">
      {/* 行内样式控制 */}
      <div style={{ color: 'red'}}>this is span</div>

      {/* 内部样式控制 */}
      <div style={style}>this is span</div>

      {/* 外部样式控制 */}
      <span className='outer'>this is span</span>
    </div>
  )
}

export default App

index.css

.outer {
  background-color: blue;
}

Untitled




案例:B站评论

效果展示:

Untitled

  1. 渲染评论列表
  2. 删除评论实现
  3. 渲染导航Tab和高亮实现
  4. 评论列表排序功能实现


渲染评论列表

核心思路

  1. 使用useState维护评论列表
  2. 使用map方法对列表数据进行遍历渲染(别忘了加key)

key Code:

const [commentList, setCommentList] = useState([])
<div className="reply-list">
    {/* 评论项 */}
    {commentList.map(item => <Item key={item.id} item={item} onDel={handleDel} />)}
  </div>
</div>


实现评论删除

需求:

  1. 只有自己的评论才显示删除按钮
  2. 点击删除按钮,删除当前评论,列表中不再显示

核心思路

  1. 删除显示 - 条件渲染 2. 删除功能 - 拿到当前项id以id为条件对评论列表做filter过滤

handleDel实现列表过滤

// 删除功能
const handleDel = (id) => {
  console.log(id)
  // 对commentList做过滤处理
  setCommentList(commentList.filter(item => item.rpid !== id))
}

匹配删除 onDel

{/* 条件:user.id === item.user.id */}
{user.uid === item.user.uid &&
<span className="delete-btn" onClick={() => onDel(item.rpid)}>
  删除
</span>}


渲染Tab+点击高亮实现

需求:点击哪个tab项,哪个做高亮处理

核心思路

点击谁就把谁的type(独一无二的标识)记录下来,然后和遍历时的每一项的type做匹配,谁匹配到就设置负责高亮的类名

Code:

// 导航 Tab 数组
const tabs = [
  { type: 'hot', text: '最热' },
  { type: 'time', text: '最新' },
]

 ...

// tab切换功能
// 1. 点击谁就把谁的type记录下来
// 2. 通过记录的type和每一项遍历时的type做匹配 控制激活类名的显示
const [type, setType] = useState('hot')
const handleTabChange = (type) => {
  console.log(type)
  setType(type)
  // 基于列表的排序
  if (type === 'hot') {
    // 根据点赞数量排序 
    // lodash
    setCommentList(_.orderBy(commentList, 'like', 'desc'))
  } else {
    // 根据创建时间排序
    setCommentList(_.orderBy(commentList, 'ctime', 'desc'))
  }
}

...

<li className="nav-sort">
  {/* 高亮类名: active */}
  {tabs.map(item =>
    <span
      key={item.type}
      onClick={() => handleTabChange(item.type)}
      className={classNames('nav-item', { active: type === item.type })}>
      {item.text}
    </span>)}
</li>


排序功能实现

Untitled

需求:

点击最新,评论列表按照创建时间倒序排列(新的在前),点击最热按照点赞数排序(多的在前)

**核心思路:**把评论列表状态数据进行不同的排序处理,当成新值传给set函数重新渲染视图UI

Code:

method: 采用 lodash 来进行排序处理

// 基于列表的排序
if (type === 'hot') {
  // 根据点赞数量排序 
  // lodash
  setCommentList(_.orderBy(commentList, 'like', 'desc'))
} else {
  // 根据创建时间排序
  setCommentList(_.orderBy(commentList, 'ctime', 'desc'))
}


classnames优化类名控制

classnames是一个简单的JS库,可以非常方便的通过条件动态控制class类名的显示

Untitled

现在的问题:字符串的拼接方式不够直观,也容易出错

Untitled

理解: classNames 是一个可以执行的方法, key用来控制类型, value用来控制条件




参考:

React:

React入门到实战导学课程_哔哩哔哩_bilibili

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

超声功率放大器使用范围有哪些

超声功率放大器是一种特殊的设备&#xff0c;用于放大超声波信号的功率级别。它在各种领域都有广泛的应用范围&#xff0c;下面将详细介绍超声功率放大器的使用范围。 医学影像领域&#xff1a; 在医学影像领域&#xff0c;超声功率放大器被广泛用于超声诊断设备。它们能够放大…

VS Code中常用插件推荐

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

Linux输入设备应用编程(键盘,按键,触摸屏,鼠标)

目录 一 输入设备编程介绍 1.1 什么是输入设备呢&#xff1f; 1.2 什么是输入设备的应用编程&#xff1f; 1.3 input子系统 1.4 数据读取流程 1.5 应用程序如何解析数据 1.5.1 按键类事件&#xff1a; 1.5.2 相对位移事件 1.5.3 绝对位移事件 二 读取 struct input_e…

23111702[含文档+PPT+源码等]计算机毕业设计javaweb高校宿舍管理系统寝室管理

文章目录 **软件开发环境及开发工具&#xff1a;****项目功能介绍&#xff1a;****论文截图&#xff1a;****实现&#xff1a;****代码片段&#xff1a;** 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 软件开发环境及开发工具&#xff…

vscode文件夹折叠问题

今天发现一个vscode的文件夹显示的问题&#xff0c;首先是这样的&#xff0c;就是我的文件夹里又一个子文件夹&#xff0c;子文件夹里有一些文件&#xff0c;但是我发现无法折叠起这个子文件夹&#xff0c;总是显示全部的文件&#xff0c;这让我备份很难&#xff0c;具体参考 h…

AMEYA360:罗姆旗下蓝碧石面向电动汽车开发出AVAS专用的语音合成LSI

罗姆集团旗下的蓝碧石科技株式会社(以下简称“蓝碧石科技”)面向电动汽车(xEV)开发出AVAS(车辆接近报警系统)专用的语音合成LSI“ML22120xx”(ML22120TB、ML22120GP)。 在推动实现碳中和(无碳)社会的进程中&#xff0c;混合动力汽车和纯电动汽车(EV)的数量不断增加。由于这些车…

Sentinel 熔断规则 (DegradeRule)

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 SpringbootDubboNacos 集成 Sentinel&…

ubuntu20.04在docker下运行ros-noetic

经常折腾虚拟机各双系统 &#xff0c; 想着不如把docker利用起来&#xff0c;下面算是一个初学者使用docker运行ros的记录&#xff1a; 1. 安装 使用官方安装脚本自动安装 curl -fsSL https://test.docker.com -o test-docker.shsudo sh test-docker.sh验证是否安装成功 doc…

利用ETLCloud自动化流程实现业务系统数据快速同步至数仓

现代企业有不少都完成了数字化的转型&#xff0c;而还未转型的企业或商铺也有进行数字化转型的趋势&#xff0c;由此可见&#xff0c;数据已经成为企业决策的重要依据。企业需要先获取数据&#xff0c;将业务系统数据同步至数仓进行整合&#xff0c;然后再进行数据分析。为了更…

工业镜头中的普通(FA)工业镜头特点

普通&#xff08;FA&#xff09;工业镜头特点 焦距大小的影响情况&#xff1a; 焦距越小&#xff0c;景深越大&#xff1b; 焦距越小&#xff0c;畸变越大&#xff1b; 焦距越小&#xff0c;渐晕现象越严重&#xff0c;使像差边缘的照度降低。 光圈大小的影响情况&#xff1a;…

基于黏菌算法优化概率神经网络PNN的分类预测 - 附代码

基于黏菌算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于黏菌算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于黏菌优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

内网离线安装elasticsearch、kibana

一、软件获取 elastic kibana 二、elastic安装 解压安装即可提前可改下配置文件&#xff0c;不然可能会出现内存分配错误 三、运行elastic 需要调试看信息的话&#xff0c;可在cmd窗口运行bat&#xff0c;就会打印输出信息了。 生产kibana token bin\elasticsearch-create…

竞赛选题 深度学习驾驶行为状态检测系统(疲劳 抽烟 喝水 玩手机) - opencv python

文章目录 1 前言1 课题背景2 相关技术2.1 Dlib人脸识别库2.2 疲劳检测算法2.3 YOLOV5算法 3 效果展示3.1 眨眼3.2 打哈欠3.3 使用手机检测3.4 抽烟检测3.5 喝水检测 4 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习的驾…

2023.11.17 hadoop之HDFS进阶

目录 HDFS的机制 edits和fsimage文件 HDFS的存储原理 写入数据原理: 读取数据原理: 元数据简介 元数据存储流程 HDFS安全机制 HDFS归档机制 HDFS垃圾桶机制 接着此前的内容 https://blog.csdn.net/m0_49956154/article/details/134298109?spm1001.2014.3001.5501 …

springcloud整合nacos实现服务注册

Nacos是一个开源的分布式系统服务和基础设施解决方案&#xff0c;用于实现动态服务发现、配置管理和服务治理。它可以帮助开发人员和运维团队更好地管理微服务架构中的服务实例、配置信息和服务调用。 Nacos提供了服务注册与发现、动态配置管理、服务路由和负载均衡等功能&…

Windows 11 配置 ssh server 服务

Windows 11 配置 ssh server 服务 1. 安装 ssh server配置 ssh key 登陆设置默认使用 Powershell设置默认访问路径启动 sshd 和设置开机自动启动安装 vim (Powershell 中可以直接使用) 1. 安装 ssh server 打开 “设置” 》 “应用”&#xff0c;然后打开 “可选配置”&#x…

win10正确配置tensorRT环境

目的 使用tensorRT进行网络模型部署&#xff0c;加快推理速度 方法 安装tensorRT的过程需要对各种组件的版本进行匹配 前置安装套件有&#xff1a; 1、CUDA 2、cuDNN 3、pyCUDA 4、tensorflow或pytorch 主要记录tensorRT安装: tensorRT安装配置查询 步骤: 1、去tensorRT官网…

什么是 802.1X?它是如何工作的?

什么是 802.1X&#xff1f;它是如何工作的&#xff1f; 什么是IEEE 802.1X&#xff1f;802.1X是如何工作的&#xff1f;802.1X EAP安全是什么&#xff1f;802.1X用在哪里&#xff1f;IEEE 802.1X和Wi-Fi是否相同&#xff1f;什么是有线802.1X&#xff1f; 802.1X的安全性有多高…

【Pytest】tep环境变量、fixtures、用例三者之间的关系

tep是一款测试工具&#xff0c;在pytest测试框架基础上集成了第三方包&#xff0c;提供项目脚手架&#xff0c;帮助以写Python代码方式&#xff0c;快速实现自动化项目落地。 在tep项目中&#xff0c;自动化测试用例都是放到tests目录下的&#xff0c;每个.py文件相互独立&…

【教学类-40-06】A4骰子纸模制作6.0(3CM嵌套骰子6条+记录表带符号6条 -油墨打印A4铅画纸)

作品展示 幼儿手掌1/3大小&#xff0c;a4纸大小的铅画纸&#xff0c;打印6份 用了4K&#xff08;26*38CM&#xff09;湿拓铅画纸&#xff0c;切成4K&#xff08;21*29.7CM&#xff09;大小&#xff0c;有颜色的一面&#xff0c;打印骰子图案 &#xff08;湿拓纸制作&#xff…