1 React组件与组件树
一个使用 React 或者其他的主流前端框架(如:Vue、Svelte)创建的应用,都是由很多的组件构成的。
可以说,React应用完全由组件构成,React所做的基本上就是将组件渲染到UI,即用户界面上。React组件有如下特点:
- 每个组件都有自己的数据、js逻辑和样式
- 我们构建多个组件,并像搭乐高积木一样组合它们以构建UI
- 组件可以被重用、嵌套,不同组件之间还可以传递数据
一个用户界面上的组件具有的层次结构可以表现为组件树的形式,如YouTube上的播放界面,不同组件的嵌套、排列关系可以表现为左图的组件树:
2 初识React组件
当我们使用cra创建一个名为todolist的react项目时,初始化项目结构为:
todolist
├── README.md
├── node_modules
├── package.json
├── package-lock.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── serviceWorker.js
在这个应用中,包含了一系列执行各种操作的文件,大部分文件都与配置有关,但是有一个文件十分的不同:App.js(这是你遇到的第一个React组件)。
把这个组件代码简化如下:
// App.js
import React from 'react'
import logo from './logo.svg'
import './App.css'
function App() {
return /* something */
}
export default App
在这段代码中:
- 我们导入了一个React包、一个svg图片和一个css文件。
- 定义了一个函数App(),返回了一些看起来很像html,但是内嵌了js代码的一串东西,其实这就是JSX,一种我们构建组件时使用的特殊语言。
- 导出了一个名为App的函数。这个函数就是一个React组件。
也就是说,创建一个React组件,只需编写一个返回 JSX 或 null 的 JavaScript 函数。
3 渲染根组件
根组件是我们要渲染的组件,即囊括其他组件的组件,组件树的最顶端。根组件一般在index.js文件中定义。
我们首先清空初始化的src目录,再创建一个空的index.js文件,在其中复制代码:
import React from "react";
import ReactDOM from "react-dom/client";
function App() {
return <h1>Hello React!</h1>;
}
// React v18
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
注意:
- 新建js文件必须被命名为index.js,这是因为项目模块绑定器webpack期望入口文件是index.js。
- 第二行的
react-dom/client,以及9、10行的根节点渲染方式可能与之前的写法不一样,这是React v18的新写法。 - 使用React.StrictMode组件包裹根组件以激活严格模式,它的作用是会渲染组件两次,以便找出某些bug。同样严格模式会检查我们是否在代码中使用了过时的React API。在React中激活严格模式是一个好习惯。
(v18之前的写法:)
import React from "react";
import ReactDOM from "react-dom";
function App() {
return <h1>Hello React!</h1>;
}
ReactDOM.render(<App />,document.getElementById("root"));
4 创建及重用组件
在下面的代码中,我们定义了一个js函数,也就是创建了一个名为Pizza的组件,并将这个组件像html标签一样插入App组件。
import React from "react";
import ReactDOM from "react-dom/client";
function App() {
return (
<div>
<h1>Hello React!!!</h1>
<Pizza />
</div>
);
}
function Pizza() {
return (
<div>
<img src="pizzas/spinaci.jpg" alt="Pizza Spinaci" />
<h2>Pizza Spinaci</h2>
<p>Tomato, mozarella, spinach, and ricotta cheese</p>
</div>
);
}
//React v18
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
注意:
- 组件生成的 HTML 结构只能有一个单一的根节点。推荐使用幽灵节点作为根节点。
- 组件名开头必须大写,而不是使用驼峰命名。
- 我们可以在App组件中嵌套构建Pizza组件,但这不是一个好的选择。应该将组件独立创建,但嵌套使用。