1.React 环境搭建
1.1 什么是 React?
React 是用于构建用户界面的 JavaScript 库,由 Facebook(Meta)开发维护,是目前前端三大主流框架之一。
核心特点:
- 组件化开发:页面拆分为独立、可复用的组件,代码维护性极强
- 虚拟 DOM:通过 JS 模拟 DOM 结构,diff 算法精准更新页面,性能优异
- 单向数据流:数据自上而下流动,状态可预测,bug 更少
- 函数组件 + Hooks:摒弃复杂类组件,代码简洁、逻辑复用方便
- 生态完善:路由、状态管理、UI 组件库齐全,适配所有web项目
1.2 开发环境准备
1.2.1 安装 Node.js
React 项目依赖 Node.js 环境,必须提前安装:
- 官网下载:https://nodejs.org/(推荐 LTS 稳定版)
- 安装完成后,打开终端验证:
node -v
npm -v
输出版本号即安装成功。
1.2.2 创建 React 项目(官方推荐)
React 官方内置脚手架 create-react-app,零配置即可快速搭建项目,适合入门学习。
终端执行命令:
# 创建项目,my-react-demo 为项目名(自定义,小写无空格)
npx create-react-app my-react-demo
# 进入项目文件夹
cd my-react-demo
# 启动项目
npm start
启动成功后,浏览器默认打开,看到 React 欢迎页面即环境搭建完成。
1.3 项目目录核心文件解析
刚创建的项目文件较多,只需重点关注核心文件:
public/index.html:唯一入口HTML文件,整个React项目挂载容器src/index.js:JS入口文件,渲染根组件、挂载到页面src/App.js:默认根组件,我们主要的开发文件src/App.css:根组件样式文件package.json:项目配置、依赖包、启动命令配置
1.4 删除默认代码,开启第一个demo
1. 清空 App.js,写入基础代码:
// 导入React核心库
import React from 'react';
// 定义函数组件
function App() {
return (
<div className="App">
<h1>我的第一个React项目</h1>
<p>从零学习React,进阶高手!</p>
</div>
);
}
// 导出组件
export default App;
2. 清空 App.css 所有默认样式,自定义样式即可。刷新页面,即可看到自定义页面内容。
第二章:React 核心语法 JSX 详解
2.1 JSX 基础语法规则(必记)
2.1.1 基本结构规则
- JSX 必须有唯一根标签(多个标签必须包裹在一个父标签内)
- 标签可以单标签闭合(如 <img/>、<input/>)
- 支持多行、嵌套标签,写法和 HTML 几乎一致
2.2.2 JSX 与 HTML 核心区别(高频易错)
JSX 属于 JS 语法,部分属性和 HTML 不同,重点记忆:
- class 改为 className:class 是 JS 关键字,JSX 中用 className 定义样式类
- 行内样式必须写对象:样式属性驼峰命名(fontSize、backgroundColor)
- 所有标签严格区分大小写:小写为HTML原生标签,大写为自定义组件
2.2.3 JSX 嵌入 JS 表达式
JSX 中通过 {} 嵌入任意合法 JS 表达式(变量、运算、函数、三元运算)
示例代码:
import React from 'react';
function App() {
// 定义JS变量
const name = "张三";
const age = 22;
const Gender= 0;
return (
<div className="App">
{/* 1. 嵌入变量 */}
<h2>我的名字:{name}</h2>
{/* 2. 嵌入运算表达式 */}
<p>年龄:{age}</p>
{/* 3. 嵌入三元表达式(条件渲染核心) */}
<p>性别:{Gender==0? "女" : "男"}</p>
</div>
);
}
export default App;
注意:{} 内只能写表达式,不能写 if、for、while 等语句。
2.3 JSX 条件渲染
React 没有 v-if,通过 JS 逻辑实现条件渲染,三种常用方式:
2.3.1 三元运算(最常用)
const isLogin = true;
return (
<div>
{isLogin ? <button>退出登录</button> : <button>点击登录</button>}
</div>
)
2.3.2 逻辑与 &&(单条件显示)
适用于:满足条件显示内容,不满足不显示
const showMsg = true;
return (
<div>
{showMsg && <p>这是一条提示消息</p>}
</div>
)
2.3.3 变量赋值渲染(复杂条件)
多条件分支推荐,代码更清晰
const type = 2;
let dom = null;
if(type === 1) {
dom = <span>首页</span>
} else if(type === 2) {
dom = <span>列表页</span>
} else {
dom = <span>详情页</span>
}
return <div>{dom}</div>
2.4 JSX 列表渲染(遍历数组)
React 没有 v-for,通过 数组.map() 实现列表渲染,必须绑定 key
标准示例:
import React from 'react';
function App() {
// 列表数据
const list = [
{ id: 1, name: 'React基础' },
{ id: 2, name: 'react进阶' },
{ id: 3, name: 'react高阶' }
];
return (
<div>
<h3>教程目录</h3>
<ul>
{/* map遍历渲染列表,key唯一不重复 */}
{list.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
export default App;
key 作用:帮助 React 虚拟 DOM 精准识别节点,提升更新性能,禁止使用索引(index)作为key(复杂列表会出现bug)。
第三章:React 组件核心概念
3.1 组件是什么?
组件是 React 的核心,是独立、可复用的代码片段,一个页面可以拆分为多个组件(头部、侧边栏、列表、按钮等)。
React 18 主流:函数组件(完全摒弃类组件,本教程只讲企业主流的函数组件)
3.2 自定义组件(创建+使用)
3.2.1 创建组件
规则:组件名首字母大写,必须有 return 返回JSX结构
新建 src/components/Button.jsx 组件文件:
// 自定义按钮组件
function MyButton() {
return (
<button style={{padding: '6px 12px', margin: '0 5px'}}>
登录
</button>
)
}
// 导出组件
export default MyButton;
3.2.2 引入并使用组件
在 App.js 中引入使用:
import React from 'react';
// 导入自定义组件
import MyButton from './components/Button';
function App() {
return (
<div>
<h2>组件复用演示</h2>
{/* 使用自定义组件,可多次复用 */}
<MyButton />
<MyButton />
<MyButton />
</div>
);
}
export default App;
3.3 组件 Props 父传子传值
Props:组件接收外部传递数据的方式,只读不可修改,实现组件复用差异化。
3.3.1 基础传值
1. 父组件传值:组件标签上自定义属性传参
2. 子组件接收:函数参数 props 获取所有传值
改造按钮组件:
// 子组件 Button.jsx
function MyButton(props) {
return (
<button style={{padding: '6px 12px'}}>
{props.text}
</button>
)
}
export default MyButton;
// 父组件 App.js
<MyButton text="登录按钮" />
<MyButton text="注册按钮" />
<MyButton text="退出按钮" />
3.3.2 Props 默认值与解构赋值
简化写法,企业开发标准写法:
// 解构props + 默认值
function MyButton({ text = "登录", color = "#1677ff" }) {
return (
<button style={{padding: '6px 12px', background: color, color: '#fff', border: 'none'}}>
{text}
</button>
)
}
export default MyButton;
3.4 组件通信总结(基础)
- 父传子:Props 传参(核心、最常用)
- 子传父:父组件传递函数,子组件调用传参
- 兄弟传值:状态提升/全局状态管理
第四章:React 核心 Hooks 精讲(React 灵魂)
Hooks 是 React 16.8 新增特性,让函数组件拥有状态、生命周期、副作用,是进阶核心,所有企业项目必备。
4.1 useState 状态钩子(组件数据响应式)
作用:定义组件响应式数据,数据修改自动更新页面视图
语法:const [变量, 修改变量的方法] = useState(初始值)
4.1.1 基础用法(计数器案例)
import React, { useState } from 'react';
function App() {
// 定义响应式状态 count,初始值0
const [count, setCount] = useState(0);
return (
<div style={{padding: '20px'}}>
<h3>计数器:{count}</h3>
<button onClick={() => setCount(count + 1)}>点击+1</button>
<button onClick={() => setCount(count - 1)} style={{marginLeft: '10px'}}>点击-1</button>
</div>
);
}
export default App;
4.1.2 复杂数据状态(对象/数组)
注意:React 状态更新不可直接修改原数据,必须替换新数据
// 对象状态
const [user, setUser] = useState({ name: "张三", age: 20 });
// 修改对象状态(扩展运算符保留原有属性)
const changeUser = () => {
setUser({ ...user, age: 21 })
}
// 数组状态
const [list, setList] = useState([1,2,3]);
// 新增数组数据
const addList = () => {
setList([...list, 4])
}
4.2 useEffect 副作用钩子(生命周期替代)
作用:处理组件副作用(请求接口、操作DOM、定时器、监听事件),替代类组件所有生命周期
语法:useEffect(回调函数, 依赖数组)
4.2.1 三种执行场景
- 无依赖:组件挂载、更新时执行
- 空数组依赖 []:仅组件挂载时执行一次(常用:接口请求)
- 指定依赖 [xxx]:挂载执行 + 依赖数据变化时执行
4.2.2 常用案例
import React, { useState, useEffect } from 'react';
function App() {
const [count, setCount] = useState(0);
// 1. 挂载执行一次
useEffect(() => {
console.log("接口请求");
}, []);
// 2. count变化时执行
useEffect(() => {
console.log("count数值更新了:", count);
}, [count]);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
export default App;
4.2.3 清除副作用
定时器、监听事件需要清除,防止内存泄漏,通过 return 函数实现
useEffect(() => {
// 开启定时器
const timer = setInterval(() => {
console.log("定时器执行");
}, 1000);
// 组件卸载时清除定时器
return () => {
clearInterval(timer);
}
}, []);
4.3 useRef 获取DOM/保存变量
两大核心作用:
- 获取原生 DOM 元素
- 保存可变变量,数据更新不触发页面渲染
DOM获取案例:
import React, { useRef } from 'react';
function App() {
// 创建ref对象
const inputRef = useRef(null);
const getInputVal = () => {
// 获取DOM元素及value
console.log(inputRef.current.value);
// 聚焦输入框
inputRef.current.focus();
}
return (
<div>
<input ref={inputRef} placeholder="请输入内容" />
<button onClick={getInputVal} style={{marginLeft: '10px'}}>获取值<\button>
);
}
export default App;
4.4 常用进阶 Hooks
4.4.1 useMemo 缓存计算结果
作用:缓存复杂计算结果,避免组件重复渲染重复计算,优化性能
const sum = useMemo(() => {
return 100 + 200;
}, []); // 依赖不变,只计算一次
4.4.2 useContext 跨组件传值
作用:解决多层组件嵌套 props 层层传递的问题,实现全局/跨层传值
第五章:React 表单与事件处理
5.1 事件绑定
React 事件是合成事件,语法驼峰命名(onClick、onChange、onSubmit)
三种绑定方式:
// 1. 行内简单事件
<button onClick={() => console.log('点击')}>点我</button>
// 2. 绑定外部函数
function handleClick() {
console.log('点你了');
}
<button onClick={handleClick}>点我</button>
5.2 受控组件(表单核心)
受控组件:表单值由 React 状态控制,数据和视图双向同步,企业唯一标准写法
import React, { useState } from 'react';
function App() {
// 状态控制表单值
const [value, setValue] = useState('');
return (
<div>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="受控组件输入框"
/>
<p>实时输入内容:{value}</p>
</div>
);
}
export default App;
第六章:React 路由基础(单页面核心)
React 本身没有路由功能,需要借助第三方库react-router-dom,实现页面跳转、路由切换。
6.1 安装路由
npm install react-router-dom
6.2 基础路由配置
React Router 6 最新语法(企业主流)
1. 在 index.js 包裹路由根组件
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
2. 在 App.js 配置路由规则
import { Routes, Route, Link } from 'react-router-dom';
import Home from './pages/Home';
import List from './pages/List';
function App() {
return (
<div>
{/* 导航跳转 */}
<Link to="/">首页</Link>
<Link to="/list" style={{marginLeft: '10px'}}>列表页</Link>
{/* 路由匹配规则 */}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/list" element={<List />} />
</Routes>
</div>
);
}
export default App;
第七章:React 状态管理进阶
7.1 状态管理场景
小型项目:useState + useContext 即可
中大型项目:需要全局状态管理,主流方案:Redux
本教程讲解最简、企业高频的 Zustand(替代Redux,简洁无冗余)
7.2 Zustand 快速上手
7.2.1 安装
npm install zustand
7.2.2 创建全局状态
新建 src/store/index.js
import { create } from 'zustand';
// 创建全局状态
const useStore = create((set) => ({
// 全局数据
token: '',
userName: '游客',
// 修改数据方法
setToken: (val) => set({ token: val }),
setUserName: (val) => set({ userName: val })
}));
export default useStore;
7.2.3 组件中使用全局状态
import useStore from './store';
function App() {
// 解构全局状态和方法
const { userName, setUserName } = useStore();
return (
<div>
<p>当前用户:{userName}</p>
<button onClick={() => setUserName('React开发者')}>修改用户名</button>
</div>
);
}
export default App;
第八章:React 工程化与性能优化(高手必备)
8.1 代码规范与目录优化
标准目录结构:
src/assets:静态资源(图片、字体)src/components:公共复用组件src/pages:页面组件src/store:全局状态管理src/utils:工具函数、接口请求src/router:路由配置
第九章:React 实战小项目(巩固全知识点)
9.1 待办清单 TodoList(零基础实战)
功能:新增任务、删除任务、展示任务列表、清空任务
import React, { useState } from 'react';
function TodoList() {
// 任务列表状态
const [list, setList] = useState([
{ id: 1, text: '学习React基础' },
{ id: 2, text: '掌握Hooks用法' }
]);
// 输入框内容
const [inputVal, setInputVal] = useState('');
// 新增任务
const addTodo = () => {
if(!inputVal) return;
setList([...list, { id: Date.now(), text: inputVal }]);
setInputVal('');
}
// 删除任务
const delTodo = (id) => {
setList(list.filter(item => item.id !== id));
}
// 清空所有
const clearAll = () => {
setList([]);
}
return (
<div style={{padding: '30px', width: '500px', margin: '0 auto'}}>
<h2>React TodoList待办清单</h2>
<div style={{margin: '20px 0'}}>
<input
value={inputVal}
onChange={(e) => setInputVal(e.target.value)}
placeholder="请输入待办任务"
style={{padding: '6px 10px', width: '300px'}}
/>
<button onClick={addTodo} style={{marginLeft: '10px', padding: '6px 12px'}}>新增任务</button>
</div>
<ul style={{paddingLeft: '0'}}>
{list.map(item => (
<li key={item.id} style={{listStyle: 'none', padding: '8px 0', borderBottom: '1px solid #eee'}}>
{item.text}
<button onClick={() => delTodo(item.id)} style={{marginLeft: '20px', color: 'red', border: 'none', background: 'none', cursor: 'pointer'}}>删除</button>
</li>
))}
</ul>
{list.length > 0 && (
<button onClick={clearAll} style={{marginTop: '20px'}}>清空所有任务</button>
)}
</div>
);
}
export default TodoList;