(一)React 基础
React 是一个用于构建用户界面的JS库。框架ReactVueAngular创建时间2014 (尤雨溪)框架类型仅 UI 库 (需要结合其他工具)渐进式框架完整前端框架语言TypeScript数据绑定单向数据流双向数据绑定 + 单向数据流双向数据绑定状态管理Vuex、PiniaRxJS、NgRx路由管理vue-router官方维护独立开发者 (尤雨溪)Google适合项目组件化、交互丰富的 UI
专栏持续更新中~~
目录
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 pnpm3. 使用 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 react4. 运行开发服务器
在项目目录中执行:
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)