React笔记(二)JSX

news2024/11/24 17:25:32

一、JSX

JSX是javascript XML的简写,实际上是javascript的扩展,既有javascript的语法结构,又有XML的结构

1、JSX的规则要求

  • jsx必须要有一个根节点

如果不想产生无用的根标签,但是还要遵守JSX的语法的要求,可以使用如下两种方式

JSX必须要有一个根节点,而且编译之后在浏览器中不产生根标签,jsx可以使用如下两种方式完成

  • 使用空标签的方式来完成

const content=<>
    <h1>Hello Giles</h1><h1>Hello Woniuxy</h1>
   </>  
  • Fragment组件来完成

const content=<Fragment>
    <h1>Hello Giles</h1><h1>Hello Woniuxy</h1>
   </Fragment>  
  • JSX中的标签如果没有子元素,那么也要使用</>来作为结束

<img src='https://api.java.crmeb.net/crmebimage/store/2020/08/15/adae23e354114cd5bd8f3cae740741c23opxeh8kw2.jpg'/></img>
  或者
<img src='https://api.java.crmeb.net/crmebimage/store/2020/08/15/adae23e354114cd5bd8f3cae740741c23opxeh8kw2.jpg'/>
  • 采用驼峰式命名法
    • class---->className

    • for--->htmlFor

    • tabindex--->tabIndex

  • 为了避免分号陷阱,建议大家必须使用()将元素括起来
const content=(<></>)

2、JSX的表达式

  • 在JSX中不管是动态元素的渲染还是属性的渲染全部通过{}来进行渲染的

let name="Giles"
let age=38
let job="teacher"
let hobby=['play basketball','play football']
let avatar="https://www.baidu.com/img/flexible/logo/pc/result.png"
const template=(
    <>
        <h1>个人简介</h1>
        <div>姓名:{name}</div>
        <div>年龄:{age}</div>
        <div>工作:{job}</div>
        <div>爱好:{hobby}</div>
        <div>
            <img src={avatar}></img>
        </div>
  </>)
  • jsx的算数表达式和三元表达式

<div>是否成年:{age>=18?'成年':'未成年'}</div>
<div>虚岁:{age+1}</div>
  • 函数表达式

let idcard="610122198404084030"
const getBirthday=idcard=>idcard.slice(6,10)+"-"+idcard.slice(10,12)+"-"+idcard.slice(12,14)
const template=(
    <>
        <h1>个人简介</h1>
        <div>姓名:{name}</div>
        <div>年龄:{age}</div>
        <div>工作:{job}</div>
        <div>爱好:{hobby}</div>
        <div>
            <img src={avatar}></img>
        </div>
        <div>是否成年:{age>=18?'成年':'未成年'}</div>
        <div>虚岁:{age+1}</div>
        <div>生日:{getBirthday(idcard)}</div>
    </>)
  • 对象表达式

let user={
    name:'刘备',
    age:39,
    job:'皇帝'
}
const introduce=user=>`我叫${user.name},今年${user.age}岁,职业是${user.job}`
const template=(<>
    <div>姓名:{user.name}</div>
    <div>年龄:{user.age}</div>
    <div>职业:{user.job}</div>
    <div>
        介绍:{introduce(user)}
    </div>
</>)

3、列表渲染

import React, { Component, Fragment } from 'react'
import '@/App.css'
export default class App extends Component {

  render() {
    const orderList = [
      {
        title: '待付款',
        icon: 'icon-daifukuan'
      },
      {
        title: '待发货',
        icon: 'icon-daifahuo'
      },
      {
        title: '待收货',
        icon: 'icon-daishouhuo'
      },
      {
        title: '待评价',
        icon: 'icon-daipingjia'
      },
      {
        title: '售后/退款',
        icon: 'icon-daifukuan'
      }
    ]
    return (
      <Fragment>
        <div className='mime'>
          <div className='order-center'>
            <div className='order-center-header'>
              <div>订单中心</div>
              <div>查看全部</div>
            </div>
            <div className='order-center-body'>
              {
                orderList.map(item => <div className='order-item'>
                  <i className={'iconfont '+item.icon}></i>
                  <div>{item.title}</div>
                </div>
                )
              }
            </div>
          </div>
        </div>
      </Fragment>
    )
  }
}

二、react的样式的处理

针对于行内样式和类样式的处理如下

1、类样式

使用className="类样式名"方式来进行类样式的设置

  • 在src/assets/css/index.css

.mtable{
    border-collapse: collapse;
    width: 900px;
}
.mtable td{
   border:1px solid #ccc;
   padding:10px;
   text-align: center;
}
  • 在src/index.js中引入

import './assets/css/index.css'

2、行内样式

语法

<div style={{key:value,key:value}}></div>

当然也可以将对象提取出来

const headStyle={border:'1px solid #eee',padding:'10px',backgroundColor:'#ccc',color:'#fff'}
<th style={headStyle}>序号</th>

注意:样式名采用驼峰式命名法,如果有多个单词,每个单词的首字母必须要大写才可以。

三、引入本地图片

如果在一个组件中要引入图片,这个图片可以来自本地,也可以来自网络,来自本地图片的处理

如果要引入本地中图片,常用的方法有两种

  • 通过ES6的import方式进行导入

import logo from './assets/logo.png'
export default class App extends Component {
     render() {
         return  <Fragment>
            	<img src={logo}></img>
         </Fragment>
     }
}
  • 通过node.js的require方法引入

import logo from './assets/logo.png'
export default class App extends Component {
     render() {
         const logo=require('./assets/logo.png')
         return  <Fragment>
            	<img src={logo}></img>
         </Fragment>
     }
}

注意:如果图片是网络图片,直接写网址就可以了,无需进行其他处理,如果是网络图片,有的时候图片地址是正确的,但是图片却出不来,可能是防盗链问题。

四、虚拟DOM和jsx底层渲染机制

1、什么是虚拟DOM

在 React 中,每个 DOM 对象都有一个对应的 Virtual DOM 对象,它是 DOM 对象的 JavaScript 对象表现形式,其实就是使用 JavaScript 对象来描述 DOM 对象信息,比如 DOM 对象的类型是什么,它身上有哪些属性,它拥有哪些子元素。

下面是一个DOM对象

<div className="container">
  <h3>Hello React</h3>
  <p>React is great </p>
</div>

对应的虚拟DOM,如下

{
  type: "div",
  props: { className: "container" },
  children: [
    {
      type: "h3",
      props: null,
      children: [
        {
          type: "text",
          props: {
            textContent: "Hello React"
          }
        }
      ]
    },
    {
      type: "p",
      props: null,
      children: [
        {
          type: "text",
          props: {
            textContent: "React is great"
          }
        }
      ]
    }
  ]
}
  • 虚拟DOM如何提升效率的

精准找出发生变化的 DOM 对象,只更新发生变化的部分。

在 React 第一次创建 DOM 对象后,会为每个 DOM 对象创建其对应的 Virtual DOM 对象,在 DOM 对象发生更新之前,React 会先更新所有的 Virtual DOM 对象,然后 React 会将更新后的 Virtual DOM 和 更新前的 Virtual DOM 进行比较,从而找出发生变化的部分,React 会将发生变化的部分更新到真实的 DOM 对象中,React 仅更新必要更新的部分。

2、创建虚拟DOM的方式

2.1、使用createElement创建虚拟DOM

我们通过React对象中提供的createElement函数完成了虚拟DOM的创建,而后再通过ReactDOM的render函数将其渲染到页面的指定元素中,这种方式创建虚拟DOM的方式相对而言比较麻烦,而且循环创建多个元素的时候,还需要指定key,否则会报错。

import React from 'react';
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(document.getElementById('root'));
const helloRectEle=React.createElement("h1",null,"Hello React");
const helloWoniuEle=React.createElement("h1",null,"Hello Woniuxy");
const helloGilesEle=React.createElement("h1",null,"Hello Giles");
const containerElement=React.createElement("div",null,  [helloRectEle,helloWoniuEle,helloGilesEle]);
root.render(containerElement);

如上页面显示是正常的,但是控制台会报如下错误

Warning: Each child in a list should have a unique "key" prop.

Check the top-level render call using <div>. See https://reactjs.org/link/warning-keys for more information.
    at h1

这是因为在循环生成多个组件的时候,没有给组件加上key引起,具体修改如下

import React from 'react';
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(document.getElementById('root'));
const helloRectEle=React.createElement("h1",{key:0},"Hello React");
const helloWoniuEle=React.createElement("h1",{key:1},"Hello Woniuxy");
const helloGilesEle=React.createElement("h1",{key:2},"Hello Giles");
const containerElement=React.createElement("div",null,  [helloRectEle,helloWoniuEle,helloGilesEle]);
root.render(containerElement);

Key的作⽤: key是虚拟DOM对象的标识,在更新时标识为keys起着极其重要的作 ⽤:即当状态中的数据发⽣变化时,react会根据新数据⽣成新的虚拟 DOM,随后React进⾏新旧虚拟DOM的key的对⽐,如果存在相同的 key,若内容没变,则沿⽤之前的真实DOM,若数据变了,则⽣成新的真 实DOM,并且替换⻚⾯之前的真实DOM,若不存在key,则根据数据创 建新的真实DOM,随后进⾏⻚⾯渲染,减少不必要的元素重渲染,提升性能

1.2、使用JSX创建虚拟DOM

对于初学者来说,通过createElement方法构建用户界面属实不太友好,但是在React内部确实需要通过这种方式创建虚拟DOM对象,如何解决这个矛盾呢?

React为createElement方法创造了替代语法,让开发者可以通过类似于HTML的语法创建用户界面,在构建应用时,再使用babel将这种替换语法转换回createElement方法的调用代码,下面就是使用JSX方式创建,下面我们先来通过一段代码来看一下,后续我们再具体详细讲解JSX的语法

 const conatiner=(
            <div>
                <h1>Hello React</h1>
                <h1>Hello Woniuxy</h1>
                <h1>Hello Giles</h1>
            </div>
 )
 ReactDOM.render(conatiner,document.getElementById('root'));

实际上JSX的方式最终还是会转成第一种使用React.createElement()函数创建的方式,这里只是为了方便使用了JSX,我们编写的JSX通过babel来转换的,下面我们可以在官网上来做这个实验

下面是babel的官网:babel官方网站: Babel 中文文档 | Babel中文网 · Babel 中文文档 | Babel中文网

这里提供了将JSX的方式最终转成createElement的方式

使用JSX的方式创建虚拟DOM的步骤

  • 在body中定义一个div容器

  • 导入包

<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
 <script src="./node_modules/babel-standalone/babel.js"></script>

注意:这里要引入babel.js对JSX进行转换,首先引入之前可以通过yarn add babel-standalone方式来下载babel

  • 编写jsx

<script type="text/babel">
        const divElement=<div>
            <h1>个人介绍</h1>
            <table>
                <tr>
                    <td>姓名:</td>
                    <td>张三</td>
                </tr>
                <tr>
                    <td>年龄:</td>
                    <td>33</td>
                </tr>
                <tr>
                    <td>性别:</td>
                    <td>男</td>
                </tr>
            </table>
        </div>
</script>

JSX中的代码可以是DOM元素,也可以是以后的自定义组件

  • 渲染虚拟DOM到目标容器上

 const root=ReactDOM.createRoot(document.getElementById('app'))
 root.render(divElement)

3、JSX的底层渲染机制

jsx的底层渲染机制可以分为如下步骤

第1步:把编写好的jsx语法,编译成虚拟DOM对象
  • 基于babel-preset-react-app把JSX编译为React.createElement(...)这种格式

可以在babel中测试一下(babel的地址:Babel · Babel)

下面介绍一下React.createElement(ele,props,...children)

参数说明

|- ele:元素的标签名或者组件

|- props:元素的属性集合(对象),注意:如果没有设置过任何的属性,则此值是null

|- children:第三个以及以后的参数,都是当前元素的子节点

  • 执行createElement方法后,创建出virtual DOM虚拟DOM对象,格式如下

第2步:将虚拟DOM通过diff算法转成真实DOM

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

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

相关文章

Angular中使用drag and drop实现文件拖拽上传,及flask后端接收

效果&#xff1a;拖拽文件到组件上面时 边框变大变红 松手后发送到服务器(或者点击蓝字手动选择文件)并且把文件名显示在框内&#xff0c;美化还没做 html <div class"drapBox"><div id"drop" (dragenter)"dragenter($event)" (dragov…

AR界安卓在中国,Rokid引爆空间计算狂潮

击关注 文丨刘雨琦 你可能很难想象&#xff0c;在一个没有显示屏也没有鼠标的空间&#xff0c;仅凭一副AR眼镜和一台口袋主机&#xff0c;就能完成一篇5000字的文章。 没错&#xff0c;8月26日&#xff0c;在2023 Rokid Jungle 新品发布会现场&#xff0c;这样的场景正在真实…

前端如何走通后端接口

0 写在前面 现在基本都是前后端分离的项目了&#xff0c;那么前端小伙伴如何获取后端小伙伴接口呢&#xff1f; 1 条件 同一WiFi下&#xff0c;让后端小伙伴分享出自己的ip地址&#xff1a; 步骤1:winr调出运行界面 步骤2&#xff1a;cmd调出命令行窗口 步骤3&#xff1a;…

6. 激活层

6.1 非线性激活 ① inplace为原地替换&#xff0c;若为True&#xff0c;则变量的值被替换。若为False&#xff0c;则会创建一个新变量&#xff0c;将函数处理后的值赋值给新变量&#xff0c;原始变量的值没有修改。 import torch from torch import nn from torch.nn import …

第一次实验:Protocol Layers

第一次实验&#xff1a;Protocol Layers 捕获跟踪*Pick a URL and fetch it with* wget *or* curl*.* 检查跟踪数据包结构协议开销复用密钥*Which Ethernet header field is the demultiplexing key that tells it the next higher layer is IP?**Which IP header field is th…

关于亚马逊云科技云技能孵化营学习心得

1、活动介绍 本活动主要是面向想要全面了解亚马逊云科技 (Amazon Web Services) 云的个人&#xff0c;而不受特定技术角色的限制。内容包括亚马逊云科技云概念、亚马逊云科技服务、安全性、架构、定价和支持等等&#xff0c;此外还可以参加亚马逊的认证考试。 2、学习过程 该…

httpd协议与apache

1.http 相关概念 HTTP是处于应用层的协议&#xff0c;使用TCP传输层协议进行可靠的传送。因此&#xff0c;需要特别提醒的是&#xff0c;万维网是基于因特网的一种广泛因特网应用系统&#xff0c;且万维网采用的是HTTP&#xff08;80/TCP&#xff09;和 HTTPS&#xff08;443/…

计算机毕设 基于深度学习的人脸专注度检测计算系统 - opencv python cnn

文章目录 1 前言2 相关技术2.1CNN简介2.2 人脸识别算法2.3专注检测原理2.4 OpenCV 3 功能介绍3.1人脸录入功能3.2 人脸识别3.3 人脸专注度检测3.4 识别记录 4 最后 1 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新…

Autoware.universe部署02:高精Lanelet2地图的绘制

文章目录 引言Lanelet基础元素Lanelet2项目各个模块 一、安装Lanelet2项目1.1 安装依赖1.2 编译1.3 在ROS中使用lanelet2地图完成routing 二、Autoware Vector Map Builder绘制高精地图2.1 创建地图2.2 绘制车道线2.3 绘制路沿2.4 绘制停止线和交通灯2.5 绘制人行道2.6 绘制停车…

IntelliJ 中如何配置 Tomcat 调试

Tomcat 在 IntelliJ 中的配置要求首先你要下载 Tomcat。 设置服务器 在 IntelliJ 下面先选择 Run&#xff0c;然后选择配置运行配置。 在弹出的界面中&#xff0c;有一个编辑配置的选项。 然后在弹出的页面中选择添加。 选择 Tomcat 在弹出的添加页面中选择添加 Tomcat&…

数据分析基础-数据可视化学习笔记03-可视化的符号与表示-图形符号学

概念 图型符号学&#xff08;Cartographic Symbolization&#xff09;是地图学领域中的一个重要概念&#xff0c;涉及到如何使用不同的符号、颜色、图案和标记来在地图上表示地理信息和数据。图型符号学旨在传达地理信息&#xff0c;使得地图能够清晰、有效地传达各种空间数据…

四、前端监控之接入Sentry到项目

前言 一、前端监控之异常监控 二、前端监控之方案调研 三、前端监控之Sentry的介绍 以上是这个专题之前的几篇文章&#xff0c;欢迎观摩 Sentry的接入 1、新建项目 在sentry后台登陆后&#xff0c;进入监控项目的界面&#xff0c;如&#xff1a; 点击右上角的 add new p…

用Go编写ChatGPT插件

ChatGPT插件平台有望成为影响深远的"下一件大事"&#xff0c;因此对于开发者来说&#xff0c;有必要对ChatGPT插件的开发有一定的了解。原文: Writing a ChatGPT Plugin With Go[1] 我工作的附带福利之一是偶尔可以接触试用一些很酷的新技术&#xff0c;最近的一项技…

详细介绍如何基于ESP32实现低功耗的电子纸天气显示器--附完整源码

实现界面展示 这是一款天气显示器,由支持 wifi 的 ESP32 微控制器和 7.5 英寸电子纸(又名电子墨水)显示器供电。当前和预测的天气数据是从 OpenWeatherMap API 获取的。传感器为显示屏提供准确的室内温度和湿度。 该项目在睡眠时消耗约 14μA,在约 10 秒的清醒期…

Tomcat 部署时 war 和 war exploded区别

在 Tomcat 调试部署的时候&#xff0c;我们通常会看到有下面 2 个选项。 是选择war还是war exploded 这里首先看一下他们两个的区别&#xff1a; war 模式&#xff1a;将WEB工程以包的形式上传到服务器 &#xff1b;war exploded 模式&#xff1a;将WEB工程以当前文件夹的位置…

Qt 查找文件夹下指定类型的文件及删除特定文件

一 查找文件 bool MyXML::findFolderFileNames() {//指定文件夹名QDir dir("xml");if(!dir.exists()){qDebug()<<"folder does not exist!";return false;}//指定文件后缀名&#xff0c;可指定多种类型QStringList filter("*.xml");//指定…

js中迭代器和可迭代对象

一、迭代器 在JavaScript中&#xff0c;迭代器也是一个具体的对象&#xff0c;这个对象需要符合迭代器协议&#xff08;iterator protocol&#xff09; 迭代器协议定义了产生一系列值&#xff08;无论是有限还是无限个&#xff09;的标准方式&#xff1b; 在JavaScript中这个…

Linux安装FRP(内网穿透)

项目简介需求背景 1.FileBrowser访问地址&#xff1a;http://X.X.X.X:8181&#xff0c;该地址只能在局域网内部访问而无法通过互联网访问&#xff0c;想要通过互联网 访问到该地址需要通过公网IP来进行端口转发&#xff0c;通常家里的路由器IP都不是公网IP&#xff0c;通常公司…

2023年6月GESP C++ 一级试卷解析

2023年6月GESP C 一级试卷解析 一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 1.以下不属于计算机输出设备的有&#xff08; &#xff09;。 A.麦克风 B.音箱 C.打印机 D.显示器 【答案】A【考纲知识点】计算机基础&#xff08;一级&#xff09; 【解析…

科大讯飞永久免费GPT入口来了!!!

讯飞GPT永久免费使用入口注册链接&#xff1a;讯飞星火认知大模型-AI大语言模型-星火大模型-科大讯飞。 登录讯飞账号后&#xff0c;点击进入体验。 进入体验页面后&#xff0c;选择景点推荐。 笔者让其写一篇关于讯飞GPT介绍的文案。 讯飞GPT是一款由讯飞公司推出的人工智能语…