在 React 中使用 JSX
JSX 是 JS 与 XML 的合体,是一种基于标签的句法,能够在 JS 代码中直接定义 React 元素。JSX 是用来代替相比复杂一点的 React.createElement()
调用。
用 JSX 创建 React 元素
JSX 写法与 HTML 十分相似,比如:
// React.createElement() 调用
React.createElement("h1", { id: "title" }, "Welcome!")
// 使用 JSX 语法
<h1 id="title">Welcome</h1>
支持组件的嵌套,同时也要注意将 class
属性换为 className
,因为也是在 JS 中。
可以用花括号传入任何合法的 JS 表达式(包括 JSX 表达式):
let title = "Welcome!"
let element = <h1>{title}</h1>
let fruits = ["apple", "banana", "melon", "pine"]
let list = (
<ul>
{ fruits.map((fruit, i) => <li key={i}>{fruit}</li>) }
</ul>
)
Babel 编译
由于目前没有浏览器支持 JSX 语法,所以需要用 Babel 编译成浏览器能运行的 JS 代码。
最简单的使用方式就是在 HTML 加入:
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
然后给目标脚本 <script>
中加入 type="text/babel"
属性。
不应当在生产环境中,在浏览器中使用 Babel ,这仅供学习或开发环境中使用。生产环境中应当直接使用编译好的脚本。
创建 React 组件
可以用函数来声明一个组件:
// JSX 的属性会传入 props 中
function Title(props) {
return <h1>{props.title}</h1>
}
let title = <Title title="Welcome!" />
React 片段
一个组件只能返回一个 React 元素。如果要返回多个同辈 React 元素,可以用 React 片段:
function Article(props) {
return (
<React.Fragment>
<h1>{props.title}</h1>
<p>{props.body}</p>
</React.Fragment>
)
}
也可以用简写语法 <> ... </>
,这是个较新的特性:
function Article(props) {
return (
<>
<h1>{props.title}</h1>
<p>{props.body}</p>
</>
)
}
你也返回一个数组来包裹同辈元素,但是 React 会将其视为列表,要求指明元素的
key
属性。
webpack 打包
1. 创建项目
mkdir my-react-app
cd my-react-app
# 用 npm 构建项目,-y 表示使用默认值
npm init -y
# 安装 react、react-dom、serve 包
npm install react react-dom serve
# src 用来放代码源文件
mkdir src
项目目录结构:
my-react-app
> node_modules (folder)
> package.json
> package-lock.json
> src (folder)
> index.js
> data (folder)
> components (folder)
2. 模块化组件
在 ./src/components/
中放入 React 组件文件,比如:
// .src/components/Article.js
import React from "react"
export default function Article({ title, body }) {
return (
<>
<h1>{title}</h1>
<p>{body}</p>
</>
)
}
// .src/components/Page.js
import React from "react"
import Article from "./Article"
export default function Page({ articles }) {
return articles.map((article, i) => {
return <Article key={i} {...article} />
})
}
在 ./src/data/
中放入数据文件,比如放入 articles.json
:
[
{
"title": "Hello React",
"body": "Create your first app."
},
{
"title": "Another Article",
"body": "This is an article ..."
}
]
index.js
为应用的入口程序:
// ./src/index.js
import React from "react"
import ReactDOM from "react-dom"
import Page from "./components/Page"
import data from "./data/articles.json"
ReactDOM.render(
<Page articles={data} />,
document.getElementById("root")
)
由于 JSX 会用到 React ,所以需要 import 导入。
这里使用的 import 语句,目前大多数浏览器及 Node.js 都不支持。但是 Babel 会把 import 语句转为
require()
调用。
3. 使用 webpack 构建
# 安装 webpack 相关包
npm install --save-dev webpack webpack-cli
# 安装 Babel 依赖包
npm install babel-loader @babel/core --save-dev
webpack 默认使用的配置文件名为 webpack.config.js
,其本身也是个模块:
从 4.0.0 开始,webpack 无需配置文件就可以进行项目打包,它会使用默认设置。
// ./webpack.config.js
var path = require("path")
module.exports = {
entry: "./src/index.js",
output: {
path: path.join(__dirname, "dist"),
filename: "bundle.js"
},
module: {
rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
]
}
}
entry
指定了程序入口文件,它会根据文件中的 import 语句构建依赖图;output
中指定了将打包后的 JS 输出到./dist/bundle.js
文件中;module.rules
指定了源文件的预处理规则,这里为为所有导入的 JS 文件上使用babel-loader
,同时会排除node_modules
文件夹。
4. 指定 Babel 预设
npm install @babel/preset-env @babel/preset-react --save-dev
然后在项目的根目录新建一个 .babelrc
文件:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
5. 生成构建包
npx webpack --mode development
或者在 package.json
中添加一个 npm 脚本:
"scripts": {
"build": "webpack --mode development"
}
然后运行 npm 快捷命令:
npm run build
6. 运行构建包
在 ./dist/
放入 index.html
文件来运行生成的 bundle.js
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>My React App</title>
</head>
<body>
<div id="root"></div>
<script src="./bundle.js"></script>
</body>
</html>
源码映射
由于把代码打包为一个文件,对浏览器调试可能有些不便。可以用源码映射把构建包映射到源文件上。只需在 webpack.config.js
中添加:
module.exports = {
/* ... */
devtool: "source-map"
}
在浏览器开发者工具中的 "资源" 标签页中,会多出一个 webpack://
文件夹,该文件夹为构建包的所有源码文件。
Create React App
Create React App 是一个命令行工具,用来快速创建 React 项目:
npm install -g create-react-app
create-react-app 项目文件夹
它仅有三个依赖:React、ReactDOM、react-scripts 。其中 react-scripts 整合了 Babel、ESLint、webpack 的安装,免去了手动配置的麻烦。
执行 npm start
会在 3000 端口上启动应用。