(一)React 基础
专栏持续更新中~~
目录
2️⃣ JSX 需要使用 className 而不是 class
4️⃣ JSX 需要使用 camelCase 语法定义 HTML 属性
3. 组件的 defaultProps 和 propTypes
✅ defaultProps 和 propTypes 配合使用
📌 defaultProps 和 propTypes 的区别
一、React介绍
1.1 什么是React
React 是一个用于构建用户界面的JS库。
1.2 React 的特点
- 声明式设计 -- React 采用声明式设计,可以轻松描述应用。
- 高效 --- React 通过对 DOM 的模拟,最大限度地减少与 DOM 的交互。
- 灵活 --- React 可以与已知的库或者框架很好的配合。
- JSX --- JSX 是 JS 的语法扩展。React 开发不一定是用 JSX,但是建议使用它。
- 组件 --- 通过对 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
- 单向影响的数据流 --- React 实现了单向响应的数据流,从而减少重复代码,这也是它为什么比传统数据绑定更简单。
1.3 React VS Vue VS Angular
1. 基本概述
|
框架 |
React |
Vue |
Angular |
|
创建时间 |
2013 (Facebook) |
2014 (尤雨溪) |
2010 (Google) |
|
框架类型 |
仅 UI 库 (需要结合其他工具) |
渐进式框架 |
完整前端框架 |
|
语言 |
JavaScript / TypeScript |
JavaScript / TypeScript |
TypeScript |
|
数据绑定 |
单向数据流 |
双向数据绑定 + 单向数据流 |
双向数据绑定 |
|
状态管理 |
useState、useReducer、Redux、Zustand |
Vuex、Pinia |
RxJS、NgRx |
|
路由管理 |
react-router |
vue-router |
Angular Router |
|
官方维护 |
Meta (Facebook) |
独立开发者 (尤雨溪) |
|
|
适合项目 |
组件化、交互丰富的 UI |
轻量级、灵活应用 |
企业级、复杂应用 |
2. 语法和核心概念对比
2.1 组件语法
React 使用 JSX,Vue 和 Angular 使用 模板语法。
2.1.1 React 组件
function App() {
return <h1>Hello React</h1>;
}
2.1.2 Vue 组件
<template>
<h1>Hello Vue</h1>
</template>
<script setup> </script>
2.1.3 Angular 组件
@Component({
selector: 'app-root',
template: '<h1>Hello Angular</h1>'
})
export class AppComponent {}
2.2 数据绑定
|
对比项 |
React |
Vue |
Angular |
|
数据流 |
单向数据流 (props + state) |
双向绑定 (v-model) + 单向流 |
双向绑定 ([(ngModel)]) |
|
状态管理 |
useState、useReducer |
ref()、reactive() |
RxJS、NgRx |
2.2.1 React(单向数据流)
function App() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
2.2.2 Vue(双向数据绑定)
<template>
<input v-model="message">
</template>
<script setup>
import { ref } from 'vue';
const message = ref("Hello Vue");
</script>
2.2.3 Angular(双向数据绑定)
<input [(ngModel)]="message">
export class AppComponent { message = "Hello Angular"; }
2.3 事件绑定
|
对比项 |
React |
Vue |
Angular |
|
事件绑定 |
onClick={() => fn()} |
@click="fn" |
(click)="fn()" |
3.性能对比
|
对比项 |
React |
Vue |
Angular |
|
虚拟DOM |
diff 算法 |
优化更高效 |
真实DOM 变更较慢 |
|
首屏加载 |
快 |
更快 |
慢(需要完整引导) |
|
文件大小 |
约 42 KB |
约 35 KB |
约 500 KB |
|
渲染方式 |
CSR 、SSR 、SSG |
CSR 、SSR 、SSG |
CSR 、SSR |
Vue 和 React 都使用虚拟 DOM ,但 Vue 3 采用的 Proxy 进行数据劫持,比 React useState 方式更高效。Angular 由于使用真实 DOM,性能相对比较慢。
4.生态系统
React 生态最广,Vue 灵活,Angular 适合大型项目。
|
对比项 |
React |
Vue |
Angular |
|
组件库 |
Ant Design、MUI、Chakra UI |
Element Plus、Vuetify |
Angular Material |
|
状态管理 |
Redux、Zustand |
Vuex、Pinia |
RxJS、NgRx |
|
移动端 |
React Native |
Quasar |
Ionic |
|
服务端渲染 |
Next.js |
Nuxt.js |
Angular Universal |
5.开发体验
Vue 上手最快,React 自由度高,Angular 规则最严格。
|
对比项 |
React |
Vue |
Angular |
|
上手难度 |
⭐⭐⭐(中等) |
⭐⭐(最简单) |
⭐⭐⭐⭐(最难) |
|
开发方式 |
JSX 代码更自由 |
模板更直观 |
复杂 |
|
文档 |
官方文档丰富 |
文档清晰 |
文档较难读 |
|
社区支持 |
超大 |
大 |
企业支持强 |
6.适用场景
|
场景 |
React |
Vue |
Angular |
|
个人项目 |
✅ 适合 |
✅ 最佳选择 |
❌ 过于复杂 |
|
企业级应用 |
✅ 可用 |
✅ 适用 |
✅ 最适合 |
|
移动端 |
✅ React Native |
✅ Quasar |
✅ Ionic |
|
SEO(SSR) |
✅ Next.js |
✅ Nuxt.js |
✅ Angular Universal |
|
后台管理 |
✅ Ant Design |
✅ Element Plus |
✅ Angular Material |
|
大规模团队开发 |
✅ 可维护 |
✅ 灵活 |
✅ 最佳选择 |
选择建议:
- Vue 适合 小型项目,易上手,开发体验好。
- React 适合 中大型项目,灵活度高,生态丰富。
- Angular 适合 企业级项目,大型团队开发,架构稳定。
7. 总结
|
对比项 |
React |
Vue |
Angular |
|
学习成本 |
⭐⭐⭐ |
⭐⭐ |
⭐⭐⭐⭐ |
|
灵活性 |
⭐⭐⭐⭐ |
⭐⭐⭐ |
⭐ |
|
性能优化 |
⭐⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
⭐⭐⭐ |
|
企业级支持 |
⭐⭐⭐ |
⭐⭐ |
⭐⭐⭐⭐⭐ |
Vue → 最简单,适合个人开发者、新手学习
React → 生态最丰富,适合大型项目
Angular → 结构严谨,适合企业级开发
二、环境搭建
1. 安装node.js
如果已经安装了 node,建议使用 nvm 来管理多个 node 版本。
node: Node.js — 在任何地方运行 JavaScript
nvm: nvm文档手册 - nvm是一个nodejs版本管理工具 - nvm中文网
2. 安装 pnpm
pnpm 是一个高效的包管理工具,比 npm 和 yarn 更快。全局安装 pnpm
npm install -g pnpm
3. 使用 Vite 创建 React 项目
Vite 是一个快速的构建工具,推荐用于 React 开发。使用以下命令创建一个 React + TypeScript 项目:
pnpm create vite@latest my-react-app --template react-ts
如果想创建 React + JavaScript 项目:
pnpm create vite@latest my-react-app --template react
4. 运行开发服务器
在项目目录中执行:
pnpm dev
默认情况下,Vite 会在 http://localhost:5173 启动开发服务器。
5. 目录结构
项目创建后,基本结构如下:
my-react-app
│── public/ # 静态资源
│── src/ # 源代码
│ ├── assets/ # 静态资源(图片、CSS等)
│ ├── components/ # 组件
│ ├── App.tsx # 入口组件
│ ├── main.tsx # 入口文件
│── index.html # HTML 入口
│── package.json # 依赖管理
│── vite.config.ts # Vite 配置文件
6. 构建项目
打包生产环境代码:
pnpm build
打包后,文件会生成在 dist/ 目录中。
三、JSX 语法
JXS (JavaScript XML) 是 React 推荐的语法扩展,它允许你在 JavaScript 代码中编写类似 HTML 的代码。JSX 本质上是 React.createElement() 的语法糖,最终会被编译为 JavaScript 代码。
1. JSX 语法规则(表达式、属性、子元素)
1. JSX 表达式
在JSX 中使用 JavaScript 表达式
在JSX 语法中,可以使用 {} 将JavaScript 表达式嵌入到 JSX 代码中:
const name = "React";
const element = <h1>Hello, {name}!</h1>;
支持的表达式:
- 变量 {name}
- 函数调用 {getFullName()}
- 计算 {1 + 2}
- 逻辑运算 {isLogin ? "Welcome" : "Please Login"}
不支持的表达式:
- 语句(如 if、for)
- 代码块(如 { let x = 10; }
2. JSX 属性(Props)
字符串属性
可以使用引号 "" 直接赋值:
const element = <img src="logo.png" alt="React Logo" />;
JavaScript 表达式
使用 {} 传递动态值:
const isActive = true;
const element = <button disabled={!isActive}>Click me</button>;
传递对象
const style = { color: "blue", fontSize: "20px" };
const element = <p style={style}>This is styled text.</p>;
传递事件处理函数
const handleClick = () => alert("Clicked!");
const button = <button onClick={handleClick}>Click me</button>;
❌ 不允许的写法(不要用 class 作为属性):
const element = <div class="container">Hello</div>; // ❌ 错误
✅ React 需要用 className 代替 class:
const element = <div className="container">Hello</div>; // ✅ 正确
3. JSX 子元素
🔹 单个子元素
const element = <h1>Hello, World!</h1>;
🔹 多个子元素
多个 JSX 元素必须包裹在一个父元素中(如
或 <>)。
const element = (
<div>
<h1>Title</h1>
<p>Content</p>
</div>
);
或使用 React Fragment (<> ... ):
const element = (
<>
<h1>Title</h1>
<p>Content</p>
</>
);
🔹 组件嵌套
JSX 允许组件作为子元素:
function Welcome() {
return <h1>Welcome to React!</h1>;
}
const App = () => (
<div>
<Welcome />
</div>
);
🔹 使用数组渲染列表
const items = ["Apple", "Banana", "Cherry"];
const list = (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
4 特殊情况
🔹 条件渲染
✅ 使用三元运算符:
const isLoggedIn = true;
const element = <p>{isLoggedIn ? "Welcome back!" : "Please log in."}</p>;
✅ 使用 && 逻辑运算:
const isAdmin = true;
const element = <p>{isAdmin && "You have admin privileges."}</p>;
2. JSX 与 JavaScript 的区别
JSX(JavaScript XML)是 React 中的语法扩展,它看起来像 HTML,但本质上仍然是 JavaScript。JSX 代码最终会被 Babel 编译为纯 JavaScript 代码。下面是 JSX 和 JavaScript 的一些主要区别:
1️⃣ JSX 是 JavaScript 的语法扩展
JSX 允许在 JavaScript 代码中编写类似 HTML 的代码,而 JavaScript 不能直接写 HTML。
✅ JSX 代码
const element = <h1>Hello, React!</h1>;
❌ 纯 JavaScript 代码
const element = React.createElement("h1", null, "Hello, React!");
JSX 代码最终会被编译成纯 JavaScript,如上所示。
2️⃣ JSX 需要使用 className 而不是 class
JSX 是 JavaScript 的扩展,而 class 是 JavaScript 的关键字,因此在 JSX 中必须使用 className 代替 class。
✅ JSX
const element = <div className="container">Hello</div>;
❌ JavaScript(报错)
const element = <div class="container">Hello</div>; // ❌ React 会报错
3️⃣ JSX 中的属性需要使用大括号 {} 传递变量
✅ JSX
const name = "React"; const element = <h1>Hello, {name}!</h1>;
❌ JavaScript(不支持 JSX 语法)
const name = "React"; const element = React.createElement("h1", null, "Hello, " + name + "!");
4️⃣ JSX 需要使用 camelCase 语法定义 HTML 属性
在 JSX 中,onclick、onchange 这些 HTML 事件必须写成 camelCase 格式,如 onClick、onChange。
✅ JSX
const button = <button onClick={() => alert("Clicked!")}>Click me</button>;
❌ JavaScript
const button = React.createElement(
"button",
{ onclick: () => alert("Clicked!") }, // ❌ React 不支持小写的 `onclick`
"Click me"
);
5️⃣ JSX 需要有一个唯一的父级元素
在 JSX 中,所有 JSX 代码必须被一个唯一的父元素包裹,而 JavaScript 不需要。
✅ JSX
const element = (
<div>
<h1>Title</h1>
<p>Content</p>
</div>
);
或者使用 Fragment:
const element = (
<>
<h1>Title</h1>
<p>Content</p>
</>
);
❌ JavaScript
const element = [
React.createElement("h1", null, "Title"),
React.createElement("p", null, "Content"),
]; // ❌ 需要包裹在一个 `div` 或 `Fragment` 里
6️⃣ JSX 可以直接嵌入表达式,但不能嵌入语句
在 JSX 中,你可以使用 JavaScript 表达式(如 变量、函数调用、三元运算符),但不能使用 JavaScript 语句(如 if、for)。
✅ JSX
const isLoggedIn = true;
const message = <p>{isLoggedIn ? "Welcome back!" : "Please log in."}</p>;
❌ 错误写法
const message = if (isLoggedIn) { <p>Welcome back!</p> }; // ❌ JSX 不支持 if 语句
✅ 正确的 JSX 语法
const message = isLoggedIn ? <p>Welcome back!</p> : <p>Please log in.</p>;
7️⃣ JSX 不能使用 if 语句,但可以使用三元运算符
JavaScript 支持 if 语句,但 JSX 只能使用三元运算符 ? : 或 &&。
✅ JSX
const isAdmin = true;
const adminPanel = isAdmin ? <p>Admin Panel</p> : null;
❌ JavaScript
let adminPanel;
if (isAdmin) {
adminPanel = React.createElement("p", null, "Admin Panel");
}
8️⃣ JSX 中的 style 需要使用对象
JSX 不支持直接写行内 CSS 字符串,必须使用 对象,且 CSS 需要使用 camelCase 语法。
✅ JSX
const style = { color: "blue", fontSize: "20px" };
const element = <p style={style}>Styled Text</p>;
❌ JavaScript
const element = React.createElement("p", { style: "color: blue; font-size: 20px;" }, "Styled Text"); // ❌ 报错
9️⃣ JSX 需要手动添加 key 属性给列表渲染
在 JSX 中,React 要求使用 key 来唯一标识列表项,而 JavaScript 不需要。
✅ JSX
const items = ["Apple", "Banana", "Cherry"];
const list = (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
❌ JavaScript
const items = ["Apple", "Banana", "Cherry"];
const list = React.createElement(
"ul",
null,
items.map((item, index) => React.createElement("li", { key: index }, item))
); // JavaScript 需要手动创建 `React.createElement`
✅ 总结:JSX vs JavaScript
|
对比项 |
JSX |
纯 JavaScript |
|
语法 |
类似 HTML |
纯 JavaScript |
|
HTML 结构 |
可以直接写 |
需要 React.createElement() |
|
属性名 |
使用 className、htmlFor |
class、for |
|
事件绑定 |
onClick={handleClick} |
onclick: handleClick |
|
条件渲染 |
isLogin ? "Welcome" : "Login" |
if (isLogin) {} |
|
CSS 样式 |
{ color: "red" } |
"color: red;" |
|
列表渲染 |
{items.map(item =>
|
React.createElement("ul", null, items.map(...)) |
JSX 是 React 的核心语法,它让 React 代码更易读,但本质上它仍然是 JavaScript,在运行前会被 Babel 编译为纯 JavaScript 代码! 🚀
四、组件基础
1. React 组件的概念
React 组件(Component) 是 React 应用的 基本构建块,用于 封装 UI 逻辑,使界面可复用、模块化、易维护。
在 React 中,组件本质上是 JavaScript 函数(或类),它们返回 JSX(类似 HTML 的语法),然后 React 负责将其渲染到页面上。
1.1 组件的两种类型
React 组件主要分为 函数组件(Function Component) 和 类组件(Class Component)。
✅ 函数组件(Function Component)
函数组件 是使用 JavaScript 的函数定义的,它接受 props 作为参数,并返回 JSX。
function Welcome(props) {
return <h1>Hello, {props.name}!</h1>;
}
// 使用组件
<Welcome name="React" />
- 特点:
- 语法简洁,易读易维护
- 支持 React Hooks(如 useState、useEffect)
- 性能更优(无类组件的 this 机制)
✅ 类组件(Class Component)
类组件 继承自 React.Component,必须实现 render() 方法返回 JSX。
import React, { Component } from "react";
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
// 使用组件
<Welcome name="React" />
- 特点:
- 需要使用 this.props
- 支持 state 和生命周期方法
- 但 React 16.8 之后,官方推荐使用 函数组件 + Hooks 代替类组件
1.2 组件的核心特性
✅ 1. 组件可以复用
function Button(props) {
return <button>{props.label}</button>;
}
export default function App() {
return (
<div>
<Button label="Click Me" />
<Button label="Submit" />
</div>
);
}
同一个 Button 组件,可以多次使用,并传入不同的 label。
✅ 2. 组件可以接收 props
props(属性) 用于组件间传递数据,类似 HTML 标签的 attributes。
function UserProfile(props) {
return <p>User: {props.username}</p>;
}
// 使用
<UserProfile username="JohnDoe" />
在类组件中:
class UserProfile extends React.Component {
render() {
return <p>User: {this.props.username}</p>;
}
}
props 只读,不能修改!
✅ 3. 组件可以有 state
state 用于存储组件的内部数据,可在组件内部修改。
在函数组件中(使用 useState):
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>;
}
在类组件中:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return <button onClick={() => this.setState({ count: this.state.count + 1 })}>Clicked {this.state.count} times</button>;
}
}
函数组件推荐使用 Hooks(如 useState),比类组件更简洁!
✅ 4. 组件生命周期(类组件)
类组件有生命周期方法,如:
- componentDidMount():组件挂载后执行(如请求数据)
- componentDidUpdate():组件更新后执行
- componentWillUnmount():组件销毁前执行(如清理定时器)
示例:
class Timer extends React.Component {
componentDidMount() {
console.log("组件已挂载");
}
componentWillUnmount() {
console.log("组件即将卸载");
}
render() {
return <p>Timer Running...</p>;
}
}
在 函数组件 中,使用 useEffect 代替:
import { useEffect } from "react";
function Timer() {
useEffect(() => {
console.log("组件已挂载");
return () => {
console.log("组件即将卸载");
};
}, []);
return <p>Timer Running...</p>;
}
✅ 5. 组件可以嵌套
父组件可以包含子组件:
function Header() {
return <h1>Welcome to React</h1>;
}
function App() {
return (
<div>
<Header />
<p>This is a React app.</p>
</div>
);
}
1.3 组件的最佳实践
✅ 1. 组件应该小而精,保持单一职责
- 错误示例:一个组件处理所有逻辑
- 正确示例:拆分成多个独立组件
✅ 2. 组件应该是可复用的
- 错误示例:硬编码在组件内
- 正确示例:使用 props 传递动态数据
✅ 3. 组件状态应该尽可能向上提升
- 避免多个组件各自管理相同的 state,可以把 state 提升到 共同的父组件
✅ 4. 组件避免不必要的渲染
- 使用 React.memo 优化函数组件
- 使用 useCallback、useMemo 记忆化数据
📌 总结
|
特性 |
函数组件 |
类组件 |
|
语法 |
function |
class |
|
props 传递 |
直接作为参数 |
this.props |
|
状态管理 |
useState() |
this.state |
|
生命周期 |
useEffect() |
componentDidMount() 等 |
|
推荐使用 |
✅(官方推荐) |
❌(React 16.8 之后不推荐) |
- 函数组件 更简洁,推荐使用
- 类组件 仍然有效,但 Hooks 已成为主流
🚀 现在 React 开发主要使用 函数组件 + Hooks!
2. 组件的 props 和 children
2.1 组件的 props 和 children
在 React 组件中,props 和 children 都是用于 数据传递 和 组件复用 的重要概念。
2.2 props (属性)
props 是 组件的输入参数,用于在 父组件向子组件 传递数据。
✅ props 的基本用法
父组件传递 props 给子组件
function UserCard(props) {
return <h2>Username: {props.name}</h2>;
}
// 父组件使用
<UserCard name="Tom" />
- 这里 props.name 传递了 "Tom",并在 UserCard 组件中渲染。
✅ props 不能修改(只读)
❌ 错误
function UserCard(props) {
props.name = "Jack"; // ❌ props 是只读的,不能修改!
return <h2>Username: {props.name}</h2>;
}
✅ 正确
- 如果需要修改数据,应该在 父组件 处理,然后通过 props 重新传递。
function App() {
const [username, setUsername] = useState("Tom");
return <UserCard name={username} />;
}
✅ props 的默认值
有时候 props 可能为空,我们可以用 defaultProps 或 ES6 默认参数。
方法 1:ES6 默认参数
function UserCard({ name = "Guest" }) {
return <h2>Username: {name}</h2>;
}
方法 2:defaultProps
UserCard.defaultProps = {
name: "Guest"
};
✅ props 结构化赋值
简化 props 的写法:
function UserCard({ name, age }) {
return <h2>{name} is {age} years old.</h2>;
}
使用:
<UserCard name="Tom" age={25} />
2.3 children (子元素)
如果使用或了解过vue的话,children 更像是 solt 插槽。
children 代表 组件的内部内容,类似于 HTML 标签内的内容。
✅ children 的基本用法
function Wrapper(props) {
return <div className="wrapper">{props.children}</div>;
}
function App() {
return (
<Wrapper>
<h1>Hello React</h1>
<p>This is a React app.</p>
</Wrapper>
);
}
- props.children 代表 组件内部的所有内容
- 渲染结果:
<div class="wrapper">
<h1>Hello React</h1>
<p>This is a React app.</p>
</div>
✅ children 适用于哪些场景?
- 封装布局组件
function Card({ children }) {
return <div className="card">{children}</div>;
}
<Card>
<h2>Title</h2>
<p>Content here...</p>
</Card>
- 高阶组件(HOC)
function Border({ children }) {
return <div style={{ border: "2px solid black", padding: "10px" }}>{children}</div>;
}
<Border>
<h2>React App</h2>
</Border>
- 渲染多个子元素
function List({ children }) {
return <ul>{children}</ul>;
}
<List>
<li>Item 1</li>
<li>Item 2</li>
</List>
✅ children 作为函数
有时候,我们希望 children 作为 函数 传递,以支持更灵活的渲染。
function RenderPropsExample({ children }) {
return <div>{children("Hello from function!")}</div>;
}
<RenderPropsExample>
{(message) => <p>{message}</p>}
</RenderPropsExample>
- children 作为函数,可以动态传递数据。
2.4 props vs children
|
对比项 |
props |
children |
|
作用 |
组件的输入参数 |
组件的内部内容 |
|
传递方式 |
子内容 |
|
|
适用场景 |
组件配置(如 name, age, id ) |
组件插槽(如布局、嵌套内容) |
|
访问方式 |
props.propName |
props.children |
3. 组件的 defaultProps 和 propTypes
组件的 defaultProps 和 propTypes
在 React 组件中,defaultProps 和 propTypes 用于管理 props 的默认值和类型检查,分别解决:
- defaultProps:设置默认的 props 值,防止 props 为空时报错。
- propTypes:对 props 进行类型检查,确保传递的值符合预期。
✅ defaultProps:设置默认 props
📌 作用
当父组件没有传递某个 prop 时,defaultProps 提供默认值,确保组件能正常运行。
📌 使用方式
import React from "react";
function Button({ label, color }) {
return <button style={{ backgroundColor: color }}>{label}</button>;
}
// 设置默认 props
Button.defaultProps = {
label: "默认按钮",
color: "blue",
};
export default Button;
📌 使用示例
<Button /> // 没传 label,默认值为 "默认按钮"
<Button label="提交" color="green" /> // 传递了 label,不使用默认值
📌 适用场景
- 组件某个 prop 不是必传的,但没有时需要默认值。
- 例如:按钮的默认颜色、占位文本、是否开启某个功能等。
✅ propTypes:进行 props 类型检查
📌 作用
用于检查组件 props 的 类型是否正确,防止传递错误数据导致 bug。
📌 使用方式
import PropTypes from "prop-types";
function Button({ label, color }) {
return <button style={{ backgroundColor: color }}>{label}</button>;
}
// 设置默认 props
Button.defaultProps = {
label: "默认按钮",
color: "blue",
};
// 定义 props 类型检查
Button.propTypes = {
label: PropTypes.string, // label 必须是字符串
color: PropTypes.string, // color 必须是字符串
};
export default Button;
📌 适用场景
- 组件需要 明确的类型约束,避免错误传参。
- 例如:number 类型的 count 不能传 string。
✅ defaultProps 和 propTypes 配合使用
import PropTypes from "prop-types";
function Card({ title, content, showBorder }) {
return (
<div style={{ border: showBorder ? "1px solid black" : "none" }}>
<h3>{title}</h3>
<p>{content}</p>
</div>
);
}
// 设置默认值
Card.defaultProps = {
title: "默认标题",
content: "这里是默认内容",
showBorder: true,
};
// 设置类型检查
Card.propTypes = {
title: PropTypes.string.isRequired, // 必须传递
content: PropTypes.string,
showBorder: PropTypes.bool,
};
export default Card;
📌 defaultProps 和 propTypes 的区别
|
对比项 |
defaultProps |
propTypes |
|
作用 |
设置默认值 |
进行类型检查 |
|
影响 |
影响组件 props 的默认值 |
不影响 props 运行 |
|
什么时候触发 |
当 props 为空时 |
传递的 props 类型错误时 |
|
是否会影响生产环境 |
✅ 会生效 |
❌ 仅在开发环境生效 |
|
是否必须 |
❌ 不是必须的 |
❌ 不是必须的 |
📌 注意事项
- React 18 及之后的版本推荐使用 TypeScript,而不是 propTypes 进行类型检查。
- defaultProps 在 Function Component 已逐步被 ES6 默认参数替代:
function Button({ label = "默认按钮", color = "blue" }) {
return <button style={{ backgroundColor: color }}>{label}</button>;
}
- propTypes 仅在开发环境生效,生产环境不会报错。
📌 结论
✅ defaultProps 解决的是 props 为空时的默认值,适合给非必填 props 赋值。
✅ propTypes 解决的是 props 类型检查,适合约束 props 类型,避免错误传参。
✅ 如果项目使用 TypeScript,可以直接使用 interface 代替 propTypes。
更多推荐



所有评论(0)