React 组件
React 组件
React 组件是构建 React 应用的基本单元,可以把组件理解为可复用的、独立的 UI 单元,每个组件封装了自己的结构、样式、逻辑和状态。
React 组件是构建应用的基石,组件可以小到一个按钮,也可以大到整个页面。
组件可以分为:函数组件和类组件。
从技术角度讲,React 组件就是一个返回 React 元素(通常是 JSX)的 JavaScript 函数或类。
// 最简单的组件
function Hello() {
return
Hello, World!
;}
将复杂的 UI 拆分成组件树:
App
├── Header
│ ├── Logo
│ └── Navigation
│ ├── NavItem
│ └── NavItem
├── Main
│ ├── Sidebar
│ └── Content
│ ├── Article
│ └── Article
└── Footer
函数组件
函数组件是定义组件的一种简洁方法。
函数组件是一个接受 props 并返回 React 元素的 JavaScript 函数。
基础语法:
// 方式 1:函数声明
function Welcome(props) {
return
Hello, {props.name}
;}
// 方式 2:箭头函数
const Welcome = (props) => {
return
Hello, {props.name}
;};
// 方式 3:简化写法(单行返回)
const Welcome = (props) =>
Hello, {props.name}
;创建一个简单的函数组件:
src/Welcome.js 文件:
import React from 'react';
// 定义一个函数组件
function Welcome(props) {
return
Hello, {props.name}!
;}
export default Welcome;
在 src/index.js 中渲染该组件:
src/index.js 文件:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Welcome from './Welcome';
const root = ReactDOM.createRoot(document.getElementById("root"));
// 渲染 Welcome 组件,并传递 name 属性
root.render(
这个例子展示了一个接受 name 属性并在页面上显示 "Hello, World!" 的简单组件。
类组件
类组件使用 ES6 类语法定义,通常用于需要管理状态或使用生命周期方法的情况。
基础语法:
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return
Hello, {this.props.name}
;}
}
创建一个类组件:
实例
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return
Hello, {this.props.name}!
;}
}
export default Welcome;
在 src/index.js 中渲染该组件:
实例
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Welcome from './Welcome';
const root = ReactDOM.createRoot(document.getElementById("root"));
// 渲染 Welcome 组件,并传递 name 属性
root.render(
测试实例
接下来我们封装一个输出 "Hello World!" 的组件,组件名为 HelloMessage:
React 实例
function HelloMessage(props) {
return
Hello World!
;}
const element =
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
element
);
尝试一下 »
实例解析:
1、我们可以使用函数定义了一个组件:
function HelloMessage(props) {
return
Hello World!
;}
你也可以使用 ES6 class 来定义一个组件:
class Welcome extends React.Component {
render() {
return
Hello World!
;}
}
2、const element =
注意,原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。
如果我们需要向组件传递参数,可以使用 this.props 对象,实例如下:
React 实例
function HelloMessage(props) {
return
Hello {props.name}!
;}
const element =
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
element
);
尝试一下 »
以上实例中 name 属性通过 props.name 来获取。
注意,在添加属性时,
class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
复合组件
我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。
以下实例我们实现了输出网站名字和网址的组件:
React 实例
function Name(props) {
return
网站名称:{props.name}
;}
function Url(props) {
return
网站地址:{props.url}
;}
function Nickname(props) {
return
网站小名:{props.nickname}
;}
function App() {
return (
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
);
尝试一下 »
实例中 App 组件使用了 Name、Url 和 Nickname 组件来输出对应的信息。
Props(属性)
Props 是组件之间传递数据的方式,类似于函数的参数。
基础用法
// 父组件传递 props
function App() {
return (
);
}
// 子组件接收 props
function Greeting(props) {
return (
Hello, {props.name}!
Age: {props.age}
);
}
Props 解构
// 推荐:直接解构
function Greeting({ name, age }) {
return (
Hello, {name}!
Age: {age}
);
}
// 带默认值的解构
function Button({ text = "Submit", variant = "primary", disabled = false }) {
return (
{text}
);
}
Props 的类型
Props 可以是任何 JavaScript 值:
function Demo() {
const user = { name: "Alice", age: 25 };
const numbers = [1, 2, 3, 4, 5];
const handleClick = () => alert("Clicked!");
return (
// 字符串 title="Hello" // 数字 count={42} // 布尔值 isActive={true} // 数组 items={numbers} // 对象 user={user} // 函数 onClick={handleClick} // JSX children={ This is content
/>
);
}
Children Props
特殊的 props,用于传递组件的子内容:
// 方式 1:使用 props.children
function Card(props) {
return (
{props.children}
);
}
// 方式 2:解构 children
function Card({ children, title }) {
return (
{title &&
{title}
});
}
// 使用
function App() {
return (
This is the card content
);
}
Props 的不可变性
重要原则:永远不要修改 props!
// 错误:修改 props
function BadComponent(props) {
props.name = "Changed"; // 绝对不要这样做!
return
{props.name}
;}
// 正确:将 props 视为只读
function GoodComponent({ name }) {
const displayName = name.toUpperCase(); // 创建新值
return
{displayName}
;}
组件的组合与复用
组合模式
// 基础组件
function Avatar({ src, alt }) {
return ;
}
function UserInfo({ name, email }) {
return (
{name}
{email}
);
}
// 组合成复杂组件
function UserCard({ user }) {
return (
);
}
容器组件模式
// 容器组件:处理逻辑和状态
function Panel({ title, children, collapsible = false }) {
const [isOpen, setIsOpen] = useState(true);
return (
{title}
{collapsible && (
{isOpen ? "Collapse" : "Expand"}
)}
{isOpen && (
{children}
)}
);
}
// 使用
function App() {
return (
Your settings here...
);
}
高阶组件思想(通过组合实现)
// 通用的加载状态包装
function WithLoading({ isLoading, children }) {
if (isLoading) {
return
}
return children;
}
// 使用
function UserList({ users, isLoading }) {
return (
- {user.name}
{users.map(user => (
))}
);
}
组件命名规范
命名规则
// 正确:大写字母开头(PascalCase)
function UserProfile() { }
function BlogPost() { }
function NavBar() { }
// 错误:小写字母开头
function userProfile() { } // React 会将其视为 HTML 标签
文件命名
// 推荐的文件结构
src/
├── components/
│ ├── Button.jsx // 或 Button.js
│ ├── UserCard.jsx
│ ├── Navigation/
│ │ ├── Navigation.jsx
│ │ ├── NavItem.jsx
│ │ └── index.js // 导出 Navigation
组件的导出与导入
默认导出
// Button.jsx
export default function Button({ text }) {
return ;
}
// App.jsx
import Button from './Button';
命名导出
// components.jsx
export function Button({ text }) {
return ;
}
export function Input({ value, onChange }) {
return ;
}
// App.jsx
import { Button, Input } from './components';
混合导出
// Card.jsx
export default function Card({ children }) {
return
}
export function CardHeader({ title }) {
return
}
export function CardBody({ children }) {
return
}
// App.jsx
import Card, { CardHeader, CardBody } from './Card';
组件设计原则
1. 单一职责原则
每个组件应该只做一件事。
// 不好:组件做太多事情
function UserDashboard() {
// 获取用户数据
// 处理表单
// 显示图表
// 处理导航
// ...
}
// 好:拆分成多个组件
function UserDashboard() {
return (
);
}
2. 保持组件简洁
组件代码不应该超过 200-300 行。
// 好:提取子组件
function ProductCard({ product }) {
return (
);
}
3. 合理使用 Props
不要传递过多的 props。
// 不好:props 过多
function User({ name, age, email, address, phone, company, role, ... }) { }
// 好:使用对象
function User({ user }) {
const { name, age, email } = user;
// ...
}
4. 避免深层嵌套
过深的组件嵌套会导致 props drilling 问题。
// 问题:props 需要层层传递
// 解决:使用 Context 或状态管理
【心得】學校任務-鑽石取得所需估計棒棒糖量
马来西亚的南方门户,一个被简称为JB的城市