React 简介

2023-09-16 23:15:00

 🎬 岸边的风:个人主页

 🔥 个人专栏 :《 VUE 》 《 javaScript 》

⛺️ 生活的理想,就是为了理想的生活 !

在这里插入图片描述

目录

Component

JSX

Multiple components

props: passing data to components

Some notes


我们现在将开始入门的可能是本课程最重要的主题,即React-库。让我们从制作一个简单的React应用开始,同时了解React的核心概念。

到目前为止,最简单的方法是使用一个叫做create-react-app的工具来开始。如果随Node一起安装的npm工具的版本号是5.3以上,那么在你的机器上安装create-react-app是可行的(但不是必须的)。

让我们创建一个名为part1的应用,并进入其目录。

npx create-react-app part1
cd part1

该应用的运行方式如下

npm start

默认情况下,该应用在本地主机的3000端口运行,地址为http://localhost:3000

默认浏览器应该自动启动。立即打开浏览器的控制台。同时打开一个文本编辑器,这样你就可以在屏幕上同时查看代码和网页。

fullstack content

应用的代码位于src文件夹中。让我们简化默认代码,使文件index.js的内容如下所示:

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

import App from './App'

ReactDOM.createRoot(document.getElementById('root')).render(<App />)copy

而文件App.js看起来是这样的:

const App = () => (
  <div>
    <p>Hello world</p>
  </div>
)

export default Appcopy

文件App.cssApp.test.jsindex.csslogo.svgsetupTests.js 和 reportWebVitals.js 可以删除,因为它们现在在我们的应用中并不需要。

如果你最后出现了以下错误

fullstack content

可能由于某种原因使用了比当前18版本更早的React版本。

修复方法是修改index.js,如下所示

import ReactDOM from "react-dom"
import App from "./App"

ReactDOM.render(<App />, document.getElementById("root"))copy

你很可能需要为你的其他项目做相同的事情。

关于版本差异的更多信息,请参见这里

Component

文件App.js现在定义了一个名为AppReact组件。在文件index.js的最后一行的命令:

ReactDOM.createRoot(document.getElementById('root')).render(<App />)copy

将其内容渲染到div-元素中,该元素在文件public/index.html中定义,其id值为'root'。

默认情况下,文件public/index.html不包含任何我们在浏览器中可见的HTML标记。你可以尝试在该文件中添加一些HTML。当使用React时,所有需要渲染的内容通常被定义为React组件。

让我们仔细看一下定义组件的代码。

const App = () => (
  <div>
    <p>Hello world</p>
  </div>
)copy

正如你可能猜到的,这个组件将被渲染成一个div-标签,它包裹着一个p-标签,其中包含了文本Hello world

从技术角度来说,该组件被定义为一个JavaScript函数。下面是一个函数(它不接收任何参数):

() => (
  <div>
    <p>Hello world</p>
  </div>
)copy

然后这个函数被分配给一个常量变量App

const App = ...copy

有几种方法可以在JavaScript中定义函数。这里我们将使用箭头函数,它在较新的JavaScript版本中被描述为ECMAScript 6,也称为ES6。

因为函数只由一个表达式组成,所以我们使用了一个简写,表示这一段代码。

const App = () => {
  return (
    <div>
      <p>Hello world</p>
    </div>
  )
}copy

换句话说,该函数返回表达式的值。

定义该组件的函数可以包含任何种类的JavaScript代码。把你的组件修改成如下样子,观察控制台中发生了什么。

const App = () => {
  console.log('Hello from component')
  return (
    <div>
      <p>Hello world</p>
    </div>
  )
}copy

也可以在一个组件内渲染动态内容。

修改组件如下。

const App = () => {
  const now = new Date()
  const a = 10
  const b = 20

  return (
    <div>
      <p>Hello world, it is {now.toString()}</p>
      <p>
        {a} plus {b} is {a + b}
      </p>
    </div>
  )
}copy

大括号内的任何JavaScript代码都会被计算,计算的结果会被嵌入到组件产生的HTML中的定义位置。

JSX

看起来React组件返回的是HTML标记。然而,事实并非如此。React组件的布局大多是用JSX编写的。虽然JSX如下所示:HTML,但我们实际上是在处理一种写JavaScript的方式。底层上,由React组件返回的JSX被编译成JavaScript。

编译后,我们的应用如下所示:

const App = () => {
  const now = new Date()
  const a = 10
  const b = 20
  return React.createElement(
    'div',
    null,
    React.createElement(
      'p', null, 'Hello world, it is ', now.toString()
    ),
    React.createElement(
      'p', null, a, ' plus ', b, ' is ', a + b
    )
  )
}copy

编译是由Babel处理的。用create-react-app创建的项目被配置为自动编译。我们将在本课程的第7章节中学习更多关于这个主题的内容。

也可以把React写成 "纯JavaScript "而不使用JSX。不过,理智的人不会这么做的。

实际上,JSX很像HTML,区别在于使用JSX,你可以通过在大括号内编写适当的JavaScript来轻松嵌入动态内容。JSX的理念与许多模板语言非常相似,例如与Java Spring一起使用的Thymeleaf,它被用在服务器上。

JSX是"XML-like"语言,这意味着每个标签都需要被关闭。例如,换行是一个空元素,在HTML中可以写成如下。

<br>copy

但在编写JSX时,标签需要被关闭。

<br />copy

Multiple components

让我们修改文件App.js如下(注:在这些示例中,底部的export 部分被省略,现在和将来都是如此。但它仍然是代码正常工作所必须的)。

const Hello = () => {  return (    <div>      <p>Hello world</p>    </div>  )}
const App = () => {
  return (
    <div>
      <h1>Greetings</h1>
      <Hello />    </div>
  )
}

我们定义了一个新的组件Hello,并在组件App中使用它。当然,一个组件可以被多次使用。

const App = () => {
  return (
    <div>
      <h1>Greetings</h1>
      <Hello />
      <Hello />      <Hello />    </div>
  )
}copy

用React编写组件是很容易的,通过组合组件,即使是比较复杂的应用也可以保持相当的可维护性。事实上,React的一个核心理念是由许多专门的可重复使用的组件组成应用。

另一个强制的惯例是在应用的组件树的顶端有一个叫做App根组件。然而,正如我们将在第6章中了解到的,有些情况下,组件App并不完全是根,而是被包裹在一个适当的实用组件中。

props: passing data to components

可以使用所谓的props向组件传递数据。

让我们对组件Hello做如下修改

const Hello = (props) => {  return (
    <div>
      <p>Hello {props.name}</p>    </div>
  )
}

现在定义组件的函数有一个参数props。作为一个参数,该参数接收一个对象,该对象有对应于组件用户定义的所有 "props "的字段。

这些prop的定义如下。

const App = () => {
  return (
    <div>
      <h1>Greetings</h1>
      <Hello name="George" />      <Hello name="Daisy" />    </div>
  )
}copy

可以有任意数量的prop,它们的值可以是 "硬编码 "的字符串或JavaScript表达式的结果。如果prop的值是用JavaScript实现的,它必须用大括号来包裹。

让我们修改代码,让组件Hello使用两个props。

const Hello = (props) => {
  return (
    <div>
      <p>
        Hello {props.name}, you are {props.age} years old      </p>
    </div>
  )
}

const App = () => {
  const name = 'Peter'  const age = 10
  return (
    <div>
      <h1>Greetings</h1>
      <Hello name="Maya" age={26 + 10} />      <Hello name={name} age={age} />    </div>
  )
}copy

组件App发送的props是变量的值、表达式的计算结果和一个常规字符串。

Some notes

React已经能生成相当清晰的错误信息。尽管如此,至少在开始的时候,你应该以非常小的步骤前进,并确保每一个改变都能如愿以偿。

控制台应始终打开。如果浏览器报告错误,不建议继续写更多的代码,寄希望有奇迹出现。相反,你应该试着理解错误的原因,比如说,回到之前的工作状态。

fullstack content

请记住,在React中,在你的代码中写console.log()命令(打印到控制台)是可行的,也是值得的。

还要记住,React组件名称必须大写。如果你尝试用以下方式定义一个组件

const footer = () => {
  return (
    <div>
      greeting app created by <a href="https://github.com/mluukkai">mluukkai</a>
    </div>
  )
}

并像这样使用它

const App = () => {
  return (
    <div>
      <h1>Greetings</h1>
      <Hello name="Maya" age={26 + 10} />
      <footer />    </div>
  )
}

页面不会显示在Footer组件中定义的内容,相反React只会创建一个空的footer元素,即内置的HTML元素,而不是同名的自定义React元素。如果你把组件名称的第一个字母改为大写字母,那么React就会创建一个定义在Footer组件中的div元素,并在页面上渲染。

注意,React组件的内容(通常)需要包含一个根元素。例如,如果我们试图定义组件App而不使用最外层的div元素。

const App = () => {
  return (
    <h1>Greetings</h1>
    <Hello name="Maya" age={26 + 10} />
    <Footer />
  )
}

结果是返回一个错误信息。

fullstack content

使用根元素并不是唯一可行的选择。一个组件的array也是一个有效的解决方案。

const App = () => {
  return [
    <h1>Greetings</h1>,
    <Hello name="Maya" age={26 + 10} />,
    <Footer />
  ]
}

然而,定义应用的根元素时,不是一个特别明智的做法,它使代码看起来有点难看。

由于根元素被强制规定了,我们在DOM树中有 "额外的 "div-elements。这可以通过使用fragments来避免,即用一个空元素来包装组件要返回的元素。

const App = () => {
  const name = 'Peter'
  const age = 10

  return (
    <>
      <h1>Greetings</h1>
      <Hello name="Maya" age={26 + 10} />
      <Hello name={name} age={age} />
      <Footer />
    </>
  )
}

现在编译成功了,由React生成的DOM也不再包含额外的div元素。

更多推荐

PKE 安全性的提升方式:Naor-Yung、Fischlin、Fujisaki-Okamoto

参考文献;[NY90]NaorM,YungM.Public-keycryptosystemsprovablysecureagainstchosenciphertextattacks[C]//Proceedingsofthetwenty-secondannualACMsymposiumonTheoryofcomputin

深入解析Perlin Simplex噪声函数:在C++中构建现代、高效、免费的3D图形背景

引言在计算机图形中,噪声是一个经常被讨论的话题。无论是为了制造自然的纹理,还是为了模拟复杂的现实世界现象,噪声函数都在其中起着关键作用。而在众多噪声函数中,PerlinSimplex噪声无疑是最受欢迎的一种。其原因不仅在于其干净、快速的特性,更因为其所提供的连续性和一致性非常适合图形渲染。本文将为你展示如何在C++中实

8路光栅尺磁栅尺编码器或16路高速DI脉冲信号转Modbus TCP网络模块 YL99-RJ45

特点:●光栅尺磁栅尺解码转换成标准ModbusTCP协议●高速光栅尺磁栅尺4倍频计数,频率可达5MHz●模块可以输出5V的电源给光栅尺或传感器供电●支持8个光栅尺同时计数,可识别正反转●可以设置作为16路独立DI高速计数器●可网页直接查看所有数据无需其他软件●编码器计数值和DI计数都支持断电自动保存●DI输入和网络通信

每天几道Java面试题:集合(第四天)

目录第四幕、第一场)大厦楼下门口第二场)大门口友情提醒背面试题很枯燥,加入一些戏剧场景故事人物来加深记忆。PS:点击文章目录可直接跳转到文章指定位置。第四幕、第一场)大厦楼下门口【面试者老王,门卫甲,门卫乙,面试者奥斯卡】门卫甲:天下熙熙皆为利来,天下攘攘皆为利往,像门卫乙和我这样不为名利专心看门,世界上又有多少人呢?

蓝牙资讯|苹果新款AirPods Pro支持Vision Pro无损音频和IP54防水防尘

苹果公司宣称,USB-C能够带来更多灵活性,现在用户可以使用手机的USB-C接口,为AirPodsPro耳机盒充电。虽然苹果没有详细介绍这款耳机,但在今天的新闻稿中依然透露了一些不一样的地方,例如新款AirPodsPro2升级到了IP54级别(原版不防尘,仅IPX4级抗水),可陪伴用户在恶劣的环境中展开冒险。除此之外,

如何用Java+SpringBoot+Vue构建一个靓车汽车销售网站?

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

阿里云通义千问大模型正式开放;玩10次ChatGPT就要消耗1升水

🦉AI新闻🚀阿里云通义千问大模型正式开放,已有超20万企业申请接入测试摘要:阿里云通义千问大模型已经通过备案并向公众开放。用户可以登录官网体验,企业用户可以通过阿里云调用API。阿里云通义千问在一个月的邀测中,就有超过20万企业和机构用户申请接入测试,并与OPPO、得物、钉钉、淘宝、浙江大学等合作。此外,阿里云还开

汇编基础(1)--ARM32

简介ARM32,也称为ARMArchitecturev7,是一种32位的指令集架构(ISA),由ARM公司开发并广泛应用于嵌入式系统和移动设备。ARM32是ARM体系结构中较早的版本,被许多处理器核使用,包括Cortex-A、Cortex-R和Cortex-M系列。ARM32架构的主要特点如下:精简指令集:ARM32使

ArmSom-W3开发板之PCIE的开发指南(二)

一、前言上一篇RK3588平台驱动调试篇[PCIE篇]-PCIE的开发指南(一)已经介绍过如何在3588上使用pcie的资源,这一篇介绍在Linux系统下如何应用pcie接上的设备二、PCI配置空间一个PCIe系统最多有256条Bus,每条Bus上最多挂32个Device,每个Device最多又能实现8个Functio

再聊Java Stream的一些实战技能与注意点

大家好,又见面了。在此前我的文章中,曾分2篇详细探讨了下JAVA中Stream流的相关操作,2篇文章收获了累计10w+阅读、2k+点赞以及5k+收藏的记录。能够得到众多小伙伴的认可,是技术分享过程中最开心的事情。不少小伙伴在评论中提出了一些的疑问或自己的独到见解,也在评论区中进行了热烈的互动讨论。梳理了下相关评论内容,

JVM 虚拟机 ----> Java 内存模型(JMM)

文章目录Java内存模型(JMM)一、运行时数据区域划分二、程序计数器(ProgramCounterRegister)计数器的作用三、Java虚拟机栈(VMStack)四、本地方法栈(NativeMethodStack)五、堆(Heap)1、概述2、新生代、老年代3、创建对象的内存分配六、元空间(MetaSpace)1

热文推荐