React入门系列:HelloWorld和JSX

本文详细介绍了如何使用React构建第一个Hello World应用,涵盖了React组件化、声明式编程思想,以及JSX语法的基本规则,帮助初学者快速上手。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

准备

前端知识基础:html,css,js
前端工程基础:nodejs,npm,webpack
开发环境准备:vs code及相关插件

快速开始

第一个应用:Hello,World!

# create-react-app是react脚手架
npm install -g create-react-app
# 用脚手架创建一个react-hello项目
create-react-app react-hello
# 删除默认的实现
cd react-hello
rm src/*
# 新建一个index.js入口文件
touch src/index.js

create-react-app会创建一个默认的web应用,可以直接运行查看效果。但为了简单起见,我们删掉它们,实现自己最简单的HelloWorld功能。

React主要编程思想是:组件化和声明式编程。在index.js定义一个HelloWorld组件并渲染到DOM里。

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

function HelloWorld() {
  return (<div>Hello,World!</div>);
}

ReactDOM.render(
  <HelloWorld />, document.querySelector('#root')
);

然后启动项目:

npm start

How it works?

一个HelloWorld搞的这么复杂,到底是怎么回事呢?

已知我们有一个public/index.html,里面超简单,定义了一个id为root的div元素:

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
</body>

从页面输出结果来看,应该是在这个div下又动态创建了一个div。最终内容大概如下:

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root">
	<div>Hello,World!</div>
  </div>
</body>

打开浏览器开发者工具,查看index.html内容,确实多了点东西:

  <script src="/static/js/bundle.js"></script><script src="/static/js/0.chunk.js"></script><script src="/static/js/main.chunk.js"></script>

这些是webpack帮我们完成的。这里面的js肯定某个地方有操作DOM创建新的div的代码。水平有限,暂时不深入。

一切都回到了render函数:

ReactDOM.render([React Element], [DOM element]);

React使用虚拟DOM的概念来与原生DOM交互,底层原理先忽略。总之React内部有一个虚拟DOM表示实际的DOM树,通过render函数调用,React会根据传入的组件元素创建实际对应的DOM元素,并把它插入到element中,这个element是实际的DOM元素。

所以index.js的功能是:定义一个名为HelloWorld的React元素,并把它插入到id为root的DOM元素内:

ReactDOM.render(
  <HelloWorld />, document.querySelector('#root')
);

React使用组件的概念来封装我们自定义的HTML元素,通常由一个方法(或ES6中的class)定义一个组件,方法返回的是一个React元素,它是可以渲染到实际DOM中的。

创建一个React元素的API为:

React.createElement(
  string|element,
  [propsObject],
  [children...]
)

其中element可以是某个DOM标签名,也可以是某个React元素。可选参数 [propsObject] 表示该元素的属性列表,可选参数 [children…] 表示该元素的子元素列表。

所以,下面两个方法是等效的:

//使用React API
function HelloWorld() {
  return React.createElement('div',{},'Hello,World!');
}

//使用JSX
function HelloWorld() {
  return (<div>Hello,World!</div>);
}

JSX简介

上面已经出现了奇怪的代码:js代码中嵌入了html代码,这种代码叫JSX。

正是这种JSX语法使得我们可以用熟悉的html语法来创建元素,免得手动调用React.createElement方法。这也是React推崇的声明式编程优于命令式编程的体现。

JSX语法通过Babel编译成实际的JavaScript。Babel是一个编译器,它可以把各种新的语法特性转换成ES5标准的JavaScript,以满足浏览器兼容性。create-react-app脚手架集成了Babel。

经过前面对React组件的认识,可以肯定,每个JSX元素定义都会转换成一个React.creatElement函数调用。

接下来要做的就是多翻翻文档,熟悉JSX的语法规则了。这里搞几个简单的示例吧。

元素名首字母大写

为了和原生html标签区分,自定义元素名首字母必须大写。并且,所有标签都必须闭合,包括html中不需要闭合的标签,如br标签。

// DO THIS:
return <br />;
return <input type='password' ... />;
return <li>text</li>;

// NOT THIS:
return <br>;
return <input type='password' ...>;
return <li>text;

组件嵌套

function Hello() {
  return <span>Hello</span>;
}

function World() {
  return <span>World</span>;
}

//HelloWorld组件内嵌套了Hello组件和World组件
function HelloWorld() {
  return (
    <div>
      <Hello/> <World/>!
    </div>
  );
}

使用括号与不使用括号

JSX规定,return后面不能直接换行。下面写法会报错:Expected an assignment or function call and instead saw an expression no-unused-expressions.

function HelloWorld() {
  return
    <div>
      <Hello/> <World/>!
    </div>;
}

实际上是因为JavaScript会在return后面加上分号,就成了:

function HelloWorld() {
  return;
    <div>
      <Hello/> <World/>!
    </div>;
}

解决这个问题要么return后面不换行,这样代码格式化稍微有点难看:

function HelloWorld() {
   return <div>
      <Hello/> <World/>!
    </div>;
}

要么使用括号:

function HelloWorld() {
  return (
    <div>
      <Hello/> <World/>!
    </div>
  );
}

JSX只能返回一个元素

当然,因为最终是调用React.createElement方法嘛。如果没有一个封闭元素,会报错,例如:

function HelloWorld() {
  return (
    <Hello /><World />
  );
}

报错内容如下:

Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>…</>?

已经给我们提示了,要么使用一个wrapper标签,如div;要么使用fragment。

当我们确实要用这些并列的元素表示代码复用的时候,可以使用fragment。例如多个td标签。

function NameCells() {
  return (
    <React.Fragment>
      <td>First Name</td>
      <td>Last Name</td>
    </React.Fragment>
  );
}

//or
function NameCells() {
  return (
    <>
      <td>First Name</td>
      <td>Last Name</td>
    </>
  );
}

使用js表达式

JSX里可以使用js表达式,例如:

function SubmitButton() {
  const buttonLabel = "Submit";
  return (
    <button>{buttonLabel}</button>
  );
}

大括号里面必须是表达式,不能是普通的语句。表达式有返回值,可以出现在赋值操作符(=)右边。

条件判断

条件判断第一种写法是三目条件运算符:

function ValidIndicator() {
  const isValid = true;
  return (
    <span>{isValid ? 'valid' : 'not valid'}</span>
  );
}

另一种是使用&操作符:

function ValidIndicator() {
  const isValid = true;
  return (
    <span>
      {isValid && 'valid'}
      {!isValid && 'not valid'}
    </span>
  );
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值