React——React基础语法(1)

摘要

本文档系统介绍了React基础语法与项目工程化实践,涵盖JSX核心规则、Hooks状态管理、组件通信机制及企业级项目结构设计,并对比了React与Vue的核心差异,适合前端开发者快速掌握React开发范式。

1. React的基础语法

1.1. React 核心概念

React 本质:

  • 用组件构建 UI
  • 数据驱动视图(state 变化 → UI 自动更新)
  • 单向数据流(父 → 子)

2. JSX 语法(React 的核心)

2.1. 什么是 JSX

复制代码
const element = <h1>Hello World</h1>;

👉 本质:

复制代码
React.createElement(...)

2.2. JSX 基本规则

2.2.1. ✔ 必须有一个根节点

复制代码
<>
  <div></div>
  <span></span>
</>

2.2.2. ✔ JS 表达式写法

复制代码
const name = "Tom";
<h1>Hello {name}</h1>

2.2.3. ✔ 条件渲染

复制代码
{isLogin ? <Home /> : <Login />}

2.2.4. ✔ 列表渲染(非常重要)

复制代码
list.map(item => <li key={item.id}>{item.name}</li>)

👉 key 必须唯一!

2.3. 组件(核心思想)

2.3.1. 函数组件(主流)

复制代码
function User() {
  return <div>User</div>;
}

2.3.2. 类组件(了解即可)

复制代码
class User extends React.Component {
  render() {
    return <div>User</div>;
  }
}

2.3.3. 组件嵌套

复制代码
function App() {
  return <User />;
}

2.4. Props(组件参数)

类似你后端的DTO入参

2.4.1. 基本用法

复制代码
function User(props) {
  return <div>{props.name}</div>;
}

<User name="Tom" />

2.4.2. 构写法(推荐)

复制代码
function User({ name }) {
  return <div>{name}</div>;
}
2.4.2.1. ✔ 函数组件必须大写
复制代码
function MyButton() {}  ✅
function myButton() {}  ❌(会被当成 HTML 标签)
2.4.2.2. ✔ 函数必须返回一个"根节点"
复制代码
return (
  <div>
    <button>按钮</button>
  </div>
);

或:

复制代码
<>
  <button />
</>

2.4.3. ✔ 函数可以接收参数(props)

复制代码
function MyButton({ text }) {
  return <button>{text}</button>;
}

使用:

复制代码
<MyButton text="删除" />

2.5. State(组件状态)

👉 类似"页面内变量",变化会触发 UI 更新

2.5.1. useState(核心)

复制代码
import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      {count}
    </button>
  );
}

2.5.2. 特点

  • 更新是异步

  • 不要直接改变量:

    count = count + 1 ❌
    setCount(count + 1) ✅

2.6. 事件处理

2.6.1. 基本事件

复制代码
<button onClick={handleClick}>点击</button>

2.6.2. 传参

复制代码
<button onClick={() => handleClick(id)}>点击</button>

2.6.3. 表单处理(重点)

复制代码
<input value={value} onChange={e => setValue(e.target.value)} />

👉 叫:受控组件

2.7. 生命周期/Hooks(重点)

2.7.1. useEffect(最重要)

复制代码
useEffect(() => {
  console.log("组件加载");

  return () => {
    console.log("组件卸载");
  };
}, []);

2.7.2. 常见场景

|----------|--------------------|
| 场景 | 用法 |
| 页面加载请求接口 | useEffect |
| 监听变量变化 | useEffect([dep]) |
| 清理定时器 | return |

2.7.3. 常见 Hooks

|-------------|--------|
| Hook | 作用 |
| useState | 状态 |
| useEffect | 副作用 |
| useRef | DOM/缓存 |
| useMemo | 性能优化 |
| useCallback | 函数缓存 |

2.8. 条件渲染 & 列表渲染(高频)

2.8.1. 条件

复制代码
{isShow && <div>显示</div>}

2.8.2. 列表

复制代码
users.map(user => (
  <div key={user.id}>{user.name}</div>
))

2.9. 组件通信(非常重要)

2.9.1. 父 → 子通信

复制代码
<Child name="Tom" />

2.9.2. 子 → 父 通信

复制代码
function Child({ onClick }) {
  return <button onClick={onClick}>点我</button>;
}

2.9.3. 跨组件(进阶)

  • Context
  • 状态管理

2.10. 表单 & 受控组件

复制代码
const [value, setValue] = useState("");

<input
  value={value}
  onChange={e => setValue(e.target.value)}
/>

👉 React 推荐:全部受控

2.11. 样式写法

2.11.1. 行内样式

复制代码
<div style={{ color: "red" }}></div>

2.11.2. className

复制代码
<div className="box"></div>

2.12. 路由(页面跳转)

👉 常用:React Router

复制代码
<Route path="/home" element={<Home />} />

2.13. 状态管理(中大型项目)

2.13.1. 常见方案

  • Context(轻量)
  • Redux(经典)
  • Pinia(Vue生态,你之前学过)

2.13.2. API请求

复制代码
useEffect(() => {
  fetch("/api/user")
    .then(res => res.json())
    .then(data => setData(data));
}, []);

2.14. ES的导入模块

复制代码
export default function MyApp() {
  return (
    <div>
      <h1>欢迎来到我的应用</h1>
      <MyButton />
    </div>
  );
}

2.14.1. export default ------ ES 模块导出

这是 JavaScript 模块语法(ES Module)

复制代码
export default function MyApp() {}

含义:

复制代码
把这个函数"默认导出",供其他文件使用

2.14.2. ✔ 使用方式:

复制代码
import MyApp from "./MyApp";

👉 注意:

  • 不需要 {}(默认导出)
  • 可以随便改名字(但一般不改)

2.14.3. function MyApp() ------ 函数组件

复制代码
function MyApp() {}

👉 在 React 中:

复制代码
返回 JSX 的函数 = 组件

👉 所以:

复制代码
MyApp 是一个"组件"

2.14.4. return (...) ------ 返回 JSX

复制代码
return (
  <div>
    <h1>欢迎来到我的应用</h1>
    <MyButton />
  </div>
);

👉 JSX(HTML + JS 语法)

JSX 做了什么?

复制代码
<div>...</div>

本质是:

复制代码
React.createElement(...)

2.14.5. 4️⃣ <MyButton /> ------ 使用组件

复制代码
<MyButton />

👉 表示:

复制代码
渲染另一个组件

👉 前提是你必须有:

复制代码
function MyButton() {
  return <button>按钮</button>;
}

3. 标准 React 项目结构(推荐)

复制代码
src/
├── main.jsx            # 入口文件(挂载 React)
├── App.jsx             # 根组件

├── assets/             # 静态资源(图片、icon、字体)
├── styles/             # 全局样式

├── components/         # 公共组件(复用)
│   ├── Table/
│   ├── Modal/
│   └── Button/

├── pages/              # 页面(路由级别)
│   ├── Manager/
│   │   ├── index.jsx
│   │   ├── service.js
│   │   └── components/
│   │       └── EditModal.jsx
│   └── Login/

├── services/           # 全局 API 请求封装
│   ├── request.js
│   └── systemField.js

├── hooks/              # 自定义 Hook(逻辑复用)
│   ├── useTable.js
│   └── useRequest.js

├── utils/              # 工具类
│   ├── format.js
│   └── auth.js

├── router/             # 路由配置
│   └── index.jsx

├── store/              # 状态管理(可选)
│   └── userStore.js

├── constants/          # 常量定义
│   └── index.js

└── config/             # 配置(环境变量等)
    └── index.js

3.1. 每一层"职责"解释(非常重要)

你可以类比后端三层架构👇

3.1.1. 1️⃣ pages(= Controller + 页面)

👉 页面入口(路由级)

复制代码
职责:
- 页面结构
- 调用接口
- 组织组件

3.1.2. 2️⃣ components(= 公共组件库)

👉 可复用 UI 组件

复制代码
特点:
- 不依赖具体业务
- 高复用

例子:

  • Table
  • Form
  • Modal

3.1.3. 3️⃣ services(= Service / API 层)

👉 专门管接口

复制代码
// systemField.js
export function queryList() {}
export function batchDelete() {}

👉 类似你后端:

复制代码
Controller → Service → DAO

3.1.4. 4️⃣ hooks(= 业务逻辑复用层)

👉 React 的"高级抽象"

复制代码
function useTable() {
  // 封装分页 / 查询逻辑
}

3.1.5. 5️⃣ utils(= 工具类)

👉 类似 Java util

  • 日期处理
  • 权限判断
  • token 处理

3.1.6. 6️⃣ router(= 路由)

👉 使用:React Router

复制代码
<Route path="/system-field" element={<SystemField />} />

3.1.7. 7️⃣ store(= 全局状态)

👉 用户信息 / 权限 / 全局数据

3.2. 企业级进阶结构(推荐)

当项目变大时👇

3.2.1. 🔥 "按业务模块拆分"(更高级)

复制代码
src/
├── modules/
│   ├── systemField/
│   │   ├── pages/
│   │   ├── components/
│   │   ├── service.js
│   │   └── hooks.js
│   ├── user/
│   └── order/

👉 优点:

  • 高内聚
  • 易扩展
  • 团队协作更清晰

3.3. 你当前场景(风控系统)推荐结构

你现在做的是:👉 特征变量管理 + 风控系统,建议直接这样👇

复制代码
src/
├── modules/
│   ├── systemField/
│   │   ├── pages/
│   │   │   └── index.jsx        # 列表页
│   │   ├── components/
│   │   │   ├── EditModal.jsx
│   │   │   └── BatchDelete.jsx
│   │   ├── service.js           # 对接你的后端接口
│   │   └── hooks.js             # 封装列表逻辑

3.4. 接口层标准写法(非常关键)

复制代码
// services/systemField.js

import request from "./request";

export function querySystemFields(params) {
  return request.post("/systemFields/query", params);
}

export function batchDeleteSystemFields(data) {
  return request.post("/systemFields/batch/delete", data);
}

👉 完美对接你刚才那个接口👇

复制代码
{
  "nameList": ["field1", "field2"]
}

3.5. 最容易踩的坑(你必须避免)

3.5.1. ❌ 1. 所有代码写在 pages(大坑)

👉 会变成 2000 行文件

3.5.2. ❌ 2. 不分 service 层

👉 页面直接写 fetch(不可维护)

3.5.3. ❌ 3. 不拆组件

👉 UI 复用性为 0

3.6. 工具类 和通用组件有什么区别? 分别是哪些内容?

复制代码
utils = 处理"数据/逻辑"
components = 处理"界面/UI"

3.6.1. utils(工具类)是什么?

复制代码
一堆"纯函数",只做计算/处理,不涉及页面

示例

复制代码
// utils/format.js
export function formatDate(date) {
  return new Date(date).toLocaleString();
}

// utils/auth.js
export function getToken() {
  return localStorage.getItem("token");
}

特点

  • ❌ 不涉及 JSX
  • ❌ 不操作 UI
  • ✅ 纯 JS 函数
  • ✅ 可复用
  • ✅ 无副作用(最好)

用途

  • 格式化数据(时间、金额)
  • token 处理
  • 加密/解密
  • 参数拼接
  • 校验逻辑

3.6.2. components(通用组件)是什么?

复制代码
一段"可复用的 UI + 交互"

📦 示例

复制代码
// components/MyButton.jsx
export default function MyButton({ onClick, children }) {
  return <button onClick={onClick}>{children}</button>;
}

📌 特点

  • ✅ 有 JSX(HTML)
  • ✅ 有 UI
  • ✅ 有交互(点击、输入)
  • ❌ 不只是函数(是组件)

🎯 用途

  • 按钮
  • 表格
  • 弹窗
  • 表单组件

3.6.3. "这个东西需要渲染页面吗?"

3.6.3.1. 需要 UI → components
复制代码
<button>点我</button>
3.6.3.2. 不需要 UI → utils
复制代码
formatDate()

4. React生命周期理解

React 的"生命周期"本质就是:组件从创建 → 更新 → 销毁的整个过程

但要注意一点:在现代 React 中(函数组件 + Hooks),生命周期不再用"钩子函数名称",而是用 useEffect****来表达。

4.1. ✅ 生命周期本质(先建立正确认知)

复制代码
组件 = 一个函数
生命周期 = 这个函数"什么时候执行 + 做什么事"

4.2. ✅ 三大生命周期阶段(核心)

4.2.1. 1️⃣ 挂载(Mount)------组件第一次出现

👉相当于:

复制代码
页面加载 / 组件第一次渲染
4.2.1.1. 📌 典型场景
  • 请求接口
  • 初始化数据
4.2.1.2. ✅ 写法(最重要)
复制代码
useEffect(() => {
  console.log("组件加载");
}, []);

👉**[]**表示:只执行一次

4.2.2. 2️⃣ 更新(Update)------数据变化

👉相当于:

复制代码
state / props 变化 → 重新渲染
4.2.2.1. 📌 典型场景
  • 搜索条件变化重新请求
  • 表单变化联动
4.2.2.2. ✅ 写法
复制代码
useEffect(() => {
  console.log("count变化了");
}, [count]);

👉只有 count****变了才执行

4.2.3. 3️⃣ 卸载(Unmount)------组件被销毁

👉相当于:

复制代码
页面离开 / 组件被移除
4.2.3.1. 📌 典型场景
  • 清理定时器
  • 取消请求
  • 解绑事件
4.2.3.2. ✅ 写法
复制代码
useEffect(() => {
  return () => {
    console.log("组件卸载");
  };
}, []);

4.3. ✅ 完整生命周期写法(你必须掌握)

复制代码
useEffect(() => {
  console.log("挂载");

  return () => {
    console.log("卸载");
  };
}, []);

useEffect(() => {
  console.log("更新");
}, [count]);

4.4. ✅ 执行顺序(非常重要)

4.4.1. 第一次渲染:

复制代码
1. 执行组件函数
2. 渲染 UI
3. 执行 useEffect(挂载)

4.4.2. 更新时:

复制代码
1. state 改变
2. 重新执行组件函数
3. 重新渲染 UI
4. 执行 useEffect(更新)

4.4.3. 卸载时:

复制代码
执行 cleanup(return 函数)

4.5. ✅ 类组件 vs 函数组件(理解差异)

4.5.1. ❌ 旧写法(类组件)

复制代码
componentDidMount()
componentDidUpdate()
componentWillUnmount()

4.5.2. ✅ 新写法(Hooks)

全部用一个:

复制代码
useEffect()

4.6. ✅ 你必须理解的关键点(重点)

4.6.1. ✔ React 没有"生命周期函数"

复制代码
只有 useEffect(副作用)

4.6.2. ✔ useEffect 控制执行时机

|------------------------|---------------|
| 写法 | 含义 |
| useEffect(fn) | 每次渲染执行 |
| useEffect(fn, []) | 只执行一次(挂载) |
| useEffect(fn, [x]) | x 变才执行 |

4.6.3. ✔ return = 清理函数

复制代码
return () => {}

👉相当于:

复制代码
componentWillUnmount

4.7. ✅ 结合你现在做的系统(非常实用)

你做风控系统,常见写法

4.7.1. 查询列表(挂载执行)

复制代码
useEffect(() => {
  fetchList();
}, []);

4.7.2. 搜索条件变化(更新执行)

复制代码
useEffect(() => {
  fetchList();
}, [query]);

4.7.3. 页面离开(清理)

复制代码
useEffect(() => {
  const timer = setInterval(() => {}, 1000);

  return () => clearInterval(timer);
}, []);

5. 解析const [count, setCount] = useState(0)

复制代码
React 没有 get 方法
count 本身就是"当前值"

这行代码本质是什么?

复制代码
const [count, setCount] = useState(0);

可以理解为:

复制代码
count = 当前值(类似 get)
setCount = 修改方法(类似 set)

怎么"获取值"?

直接用变量:

复制代码
<p>{count}</p>

或者:

复制代码
console.log(count);

❗没有这种写法:

复制代码
count.get() ❌

setCount 是怎么工作的?(重点)

复制代码
setCount(count + 1);

做了两件事:

复制代码
1. 更新状态
2. 触发组件重新执行(重新渲染)

然后:

复制代码
function MyComponent() {
  const [count, setCount] = useState(0);
}

会重新执行一遍,新的:

复制代码
count = 更新后的值

6. React中 Hook函数

在 React 中:

复制代码
Hook = 让函数组件拥有"状态 / 生命周期 / 逻辑复用能力"

统一特征:

复制代码
都以 use 开头

这些是你能写页面必须会的。

6.1. 1️⃣ useState(状态)

复制代码
const [count, setCount] = useState(0);

作用:组件数据

6.2. 2️⃣ useEffect(生命周期/副作用)

复制代码
useEffect(() => {
  fetchData();
}, []);

作用:

  • 请求接口
  • 监听变化
  • 清理资源

6.3. 3️⃣ useRef(非常重要)

复制代码
const inputRef = useRef(null);

作用:

复制代码
1. 获取 DOM
2. 保存变量(不会触发渲染)

示例

复制代码
<input ref={inputRef} />

6.4. 4️⃣ useContext(跨组件传值)

复制代码
const value = useContext(MyContext);

作用:

复制代码
替代 props 一层层传递

相当于是vue里面 useContext ≈ Vue 的 provide / inject (跨组件传递工作)

React 写法

复制代码
const UserContext = createContext();

function App() {
  return (
    <UserContext.Provider value={{ name: "Tom" }}>
      <Child />
    </UserContext.Provider>
  );
}

function Child() {
  const user = useContext(UserContext);
  return <div>{user.name}</div>;
}

Vue 写法

复制代码
// 父组件
    provide("user", { name: "Tom" });

// 子组件
const user = inject("user");

效果一样:子组件直接拿到父组件数据(跨层级)

6.5. 5️⃣ useMemo(缓存计算结果)

复制代码
const result = useMemo(() => {
  return expensiveCalc(a, b);
}, [a, b]);

作用:避免重复计算

6.6. 6️⃣ useCallback(缓存函数)

复制代码
const handleClick = useCallback(() => {
  console.log("click");
}, []);

作用:避免函数重复创建(优化性能)

6.7. 7️⃣ useReducer(复杂状态)

类似 Redux

复制代码
const [state, dispatch] = useReducer(reducer, initialState);

场景:

  • 表单复杂
  • 多状态联动

6.8. 8️⃣ useLayoutEffect

和 useEffect 类似,但:

复制代码
在 DOM 渲染前执行

场景:

  • 操作 DOM
  • 防止闪烁

6.9. 9️⃣ useImperativeHandle

配合 forwardRef 用

很少用(组件暴露方法)

6.10. 🔟 useDebugValue

调试用(开发者工具)

7. React 相关思考

7.1. React和vue 核心思想是不是一样?

可以这么说:React Vue.js 在"核心思想层面是相似的",但在"实现哲学和开发体验上差异很大"。

7.1.1. 核心思想:确实"基本一致" ✅

两者共享的核心理念:

7.1.1.1. 1️⃣ 数据驱动视图(本质一致)
复制代码
数据变化 → UI 自动更新

和你后端类比:

  • Java:对象 → JSON → 页面
  • 前端:state/data → render → UI
7.1.1.2. 2️⃣ 组件化开发(完全一致)
复制代码
页面 = 组件树
  • Button / Table / Form 全是组件
  • 可复用、可组合
7.1.1.3. 3️⃣ 单向数据流(核心一致)
复制代码
父组件 → 子组件(props)

👉 这点两者完全一样。

7.1.2. 核心差异(重点)⚠️

7.1.2.1. 1️⃣ 思维方式差异(最大区别)

|----|-------------------|---------------------|
| | React | Vue |
| 思想 | 函数式 / JS 驱动 | 模板驱动(HTML思维) |
| 写法 | JSX(JS + HTML 混写) | template(HTML + 指令) |
| 感觉 | 更"程序员" | 更"前端工程师" |

React

复制代码
{list.map(item => <div>{item}</div>)}

👉 完全 JS 思维

Vue

复制代码
<div v-for="item in list">{{ item }}</div>

👉 类似模板语言

7.1.2.2. 2️⃣ 响应式机制(本质不同)

Vue(自动响应式)

复制代码
data() {
  return { count: 0 }
}

👉 改值就更新:

复制代码
this.count++

React(手动触发)

复制代码
const [count, setCount] = useState(0);
setCount(count + 1);

👉 ❗必须手动 set

7.1.2.3. 3️⃣ 数据绑定方式

Vue:双向绑定(强)

复制代码
<input v-model="value" />

React:单向 + 手动

复制代码
<input value={value} onChange={e => setValue(e.target.value)} />

👉 React 更"可控",但更啰嗦。

7.1.2.4. 4️⃣ 生态设计理念

|------|------------------|----------------|
| | React | Vue |
| 定位 | UI 库 | 渐进式框架 |
| 官方提供 | 很少 | 很完整 |
| 路由 | 外部(React Router) | 官方(Vue Router) |
| 状态管理 | Redux / Zustand | Vuex / Pinia |

👉 简单说:

  • React:"给你积木,自己搭"
  • Vue:"给你一整套房子"

7.2. React中useState 与Vue中Vuex/Pinia的区别

复制代码
useState = 组件内状态(局部)
Vuex/Pinia = 全局状态管理(跨组件)

|-------|----------|--------------|
| 维度 | useState | Vuex / Pinia |
| 作用范围 | 当前组件 | 全局 |
| 数据共享 | ❌ 不行 | ✅ 可以 |
| 生命周期 | 组件级 | 应用级 |
| 使用复杂度 | 简单 | 较复杂 |
| 典型场景 | 表单 / 按钮 | 用户信息 / 权限 |

7.2.1. 在 React 中 useState:

复制代码
import { useState } from 'react';

const [count, setCount] = useState(0);

作用:

复制代码
给"当前组件"一个状态

7.2.2. 📌 特点

  • 只属于当前组件
  • 组件销毁就没了
  • 不能直接跨组件共享(除非传 props)

7.2.3. Vue中Vuex / Pinia 是什么

在 Vue.js 生态里:

  • Vuex(旧)
  • Pinia(新)

作用:

复制代码
全局状态管理(所有组件都能用)

7.2.4. 📌 示例(Pinia)

复制代码
export const useUserStore = defineStore('user', {
  state: () => ({
    name: 'Tom'
  })
});

👉 任意组件都能用:

复制代码
const userStore = useUserStore();

博文参考

相关推荐
pingan87872 小时前
试试 docx.js 一键生成 Word 文档,效果很不错
开发语言·前端·javascript·ecmascript·word
张一凡932 小时前
重新理解 React 状态管理:用类的方式思考业务
前端·react.js
结网的兔子3 小时前
前端学习笔记——Element Plus 栅格布局系统示例
前端·javascript·css
l1t3 小时前
DeepSeek总结的用 C# 构建 DuckDB 插件说明
前端·数据库·c#·插件·duckdb
zhensherlock3 小时前
Protocol Launcher 系列:App Store 精准引流与应用推广
javascript·macos·ios·typescript·iphone·mac·ipad
泯泷3 小时前
从零构建寄存器式 JSVMP:实战教程导读
前端·javascript·算法
椰子皮啊3 小时前
mediasoup+Vue3避坑指南:解决黑屏、闪屏、流绑定失效三大难题
vue.js·前端框架
叫我一声阿雷吧3 小时前
JS 入门通关手册(24):Promise:从回调地狱到异步优雅写法
javascript·前端开发·promise·前端面试·异步编程·js进阶·js异步
开源盛世!!4 小时前
3.19-3.21
linux·服务器·前端