1. 首页 > 电脑知识

React前端框架 进修 react框架入门

作者:admin 更新时间:2025-06-17
摘要:一、React简介与发展历程 1.1 React是什么 React是由Facebook开发并维护的一个用于构建用户界面的JavaScript库。它采用声明式语法和组件化思想,通过虚拟DOM(Virtual DOM)提高渲染效率,使开发者能够构建可复用、可维护的大型Web应用。 1.2 React的诞生与发展 2011年:React在Facebook内部诞生,最初用于Facebook的新闻信息流功能,React前端框架 进修 react框架入门

 

一、React简介与 进步历程

1.1 React是 何

React是由Facebook开发并维护的一个用于构建用户界面的JavaScript库。它采用声明式语法和组件化 想法,通过虚拟DOM(Virtual DOM) 进步渲染效率,使开发者能够构建可复用、可维护的大型Web应用。

1.2 React的诞生与 进步

2024年:React在Facebook内部诞生,最初用于Facebook的新闻信息流功能 2024年:Instagram开始采用React 2024年:React正式开源 2024年:React Native发布,允许使用React开发原生移动应用 2024年:React 15.0发布,引入Fiber架构 2024年:React 16.0发布,引入Error Boundaries、Portals等新特性 2024年:React Hooks发布,彻底改变了函数组件的使用方式 2024年:React 17.0发布,主要是架构改进,为未来版本做准备 2024年:React 18.0发布,引入并发特性和自动批处理

1.3 React的特点与优势

声明式语法:使用JSX描述UI,直观易懂 组件化:将UI拆分为独立的、可复用的组件 单向数据流:数据流动 路线明确,易于调试 虚拟DOM:通过DOM diff算法 进步渲染效率 生态 丰盛:拥有庞大的社区和 丰盛的第三方库 跨平台:可用于Web、移动端、桌面应用等多个平台

二、React核心概念

2.1 JSX

JSX(JavaScript XML)是一种JavaScript的语法扩展,允许在JavaScript代码中编写类似XML的结构。它不是必须的,但使用JSX可以更直观地描述UI结构。

2.1.1 JSX基本语法

JSX看起来像HTML,但实际上是JavaScript。在JSX中,可以:

使用花括号{}嵌入JavaScript表达式 使用className代替class( 由于class是JavaScript的保留字) 使用htmlFor代替for( 由于for是JavaScript的保留字)

下面 一个简单的JSX示例:

const element = ( <div className="greeting"> <h1>Hello, {user.name}</h1> <p>Welcome to our website!</p> </div> );
2.1.2 JSX转译 经过

JSX会被Babel等工具转译为普通的JavaScript函数调用。例如:

const element = <h1 className="greeting">Hello, world!</h1>;

会被转译为:

const element = React.createElement( 'h1', { className: 'greeting'}, 'Hello, world!' );

2.2 虚拟DOM(Virtual DOM)

虚拟DOM是React的核心概念 其中一个,它是 诚恳DOM的抽象表示,以JavaScript对象的形式存在于内存中。React通过比较新旧虚拟DOM的差异,只更新需要更新的 诚恳DOM部分,从而 进步渲染效率。

2.2.1 虚拟DOM的 职业原理

首次渲染:React创建虚拟DOM树并渲染到 诚恳DOM 数据变化:当组件的 情形或属性发生变化时,React创建新的虚拟DOM树 Diff算法:React比较新旧虚拟DOM树的差异(Diff) 最小化DOM操作:React只更新发生变化的 诚恳DOM部分

2.2.2 Diff算法的优化策略

树比较:不同类型的元素会产生不同的树 组件比较:相同类型的组件,保持实例不变 元素比较:对于同一层级的元素,通过key来识别哪些元素发生了变化

2.3 组件

组件是React应用的基本构建块,它将UI和逻辑封装在一起,使代码更易于维护和复用。

2.3.1 函数组件与类组件

函数组件:接收props并返回JSX,是无 情形组件 类组件:通过ES6的class语法定义,继承自React.Component,是有 情形组件

下面是函数组件和类组件的示例:

// 函数组件 function Welcome(props) { return <h1>Hello, {props.name}</h1>; } // 类组件 class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
2.3.2 组件的组合与复用

组件可以嵌套使用,形成组件树。这种组合方式使代码更具模块化和可复用性。

function App() { return ( <div> <Welcome name="Alice" /> <Welcome name="Bob" /> <Welcome name="Charlie" /> </div> ); }

2.4 Props

Props(Properties的缩写)是React组件的输入数据,它是只读的,不能在组件内部修改。Props使组件可以接收外部数据并进行渲染。

2.4.1 Props的基本用法
function Welcome(props) { return <h1>Hello, {props.name}</h1>; } const element = <Welcome name="Sara" />; ReactDOM.render(element, document.getElementById('root'));
2.4.2 Props的默认值

可以通过defaultProps为组件设置默认props:

function Welcome(props) { return <h1>Hello, {props.name}</h1>; } Welcome.defaultProps = { name: 'Guest' };
2.4.3 Props的类型检查

可以使用prop-types库对props进行类型检查:

import PropTypes from 'prop-types'; function Welcome(props) { return <h1>Hello, {props.name}</h1>; } Welcome.propTypes = { name: PropTypes.string.isRequired };

2.5 State

State是组件内部的 情形数据,用于存储组件的动态信息。与props不同,state是可变的,可以在组件内部修改。

2.5.1 State的基本用法(类组件)
class Clock extends React.Component { constructor(props) { super(props); this.state = { date: new Date() }; } componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); } componentWillUnmount() { clearInterval(this.timerID); } tick() { this.setState({ date: new Date() }); } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } }
2.5.2 State的更新 制度

不要直接修改State:应该使用setState() 技巧 State更新可能是异步的:React可能会批量处理多个setState()调用 State更新会合并:当调用setState()时,React会将提供的对象合并到当前state

2.5.3 State与Hooks(函数组件)

在函数组件中,可以使用useState Hook来管理state:

import React, { useState } from 'react'; function Clock() { const [date, setDate] = useState(new Date()); useEffect(() => { const timerID = setInterval( () => setDate(new Date()), 1000 ); return () => clearInterval(timerID); }, []); return ( <div> <h1>Hello, world!</h1> <h2>It is {date.toLocaleTimeString()}.</h2> </div> ); }

2.6 生活周期 技巧

生活周期 技巧是类组件特有的 技巧,它们在组件的不同阶段自动调用,允许开发者在特定 时刻点执行代码。

2.6.1 挂载阶段

constructor():组件初始化时调用 render():渲染UI componentDidMount():组件挂载到DOM后调用,适合进行API调用、事件监听等

2.6.2 更新阶段

render():重新渲染UI componentDidUpdate():组件更新后调用,适合进行DOM操作、条件性API调用等

2.6.3 卸载阶段

componentWillUnmount():组件卸载前调用,适合清理定时器、取消订阅等

2.6.4 生活周期 技巧示例
class Example extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; console.log('constructor'); } componentDidMount() { console.log('componentDidMount'); this.timer = setInterval(() => { this.setState({ count: this.state.count + 1 }); }, 1000); } componentDidUpdate(prevProps, prevState) { console.log('componentDidUpdate'); if (prevState.count !== this.state.count) { console.log('Count changed'); } } componentWillUnmount() { console.log('componentWillUnmount'); clearInterval(this.timer); } render() { console.log('render'); return ( <div> <p>Count: {this.state.count}</p> </div> ); } }

2.7 事件处理

React事件处理与原生DOM事件处理有一些区别:

命名方式:React事件使用驼峰命名法,而不是小写 传递方式:React事件通过JSX传递函数,而不是字符串 阻止默认行为:在React中必须显式调用preventDefault()

2.7.1 事件处理示例
class Button extends React.Component { handleClick = (e) => { e.preventDefault(); console.log('Button clicked'); } render() { return ( <button onClick={this.handleClick}> Click me </button> ); } }
2.7.2 向事件处理程序传递参数
class ListItem extends React.Component { handleClick = (id) => { console.log('Clicked item with ID:', id); } render() { return ( <li onClick={() => this.handleClick(this.props.id)}> {this.props.name} </li> ); } }

2.8 条件渲染

React中的条件渲染与JavaScript中的条件逻辑相同,可以使用if语句、三元运算符或逻辑与运算符来实现。

2.8.1 使用if语句
function UserGreeting(props) { return <h1>Welcome back!</h1>; } function GuestGreeting(props) { return <h1>Please sign up.</h1>; } function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />; }
2.8.2 使用三元运算符
function LoginButton(props) { return ( <button onClick={props.onClick}> Login </button> ); } function LogoutButton(props) { return ( <button onClick={props.onClick}> Logout </button> ); } function LoginControl(props) { const isLoggedIn = props.isLoggedIn; return ( <div> {isLoggedIn ? ( <LogoutButton onClick={props.onLogoutClick} /> ) : ( <LoginButton onClick={props.onLoginClick} /> )} </div> ); }
2.8.3 使用逻辑与运算符
function Mailbox(props) { const unreadMessages = props.unreadMessages; return ( <div> <h1>Hello!</h1> {unreadMessages.length > 0 && ( <h2> You have {unreadMessages.length} unread messages. </h2> )} </div> ); }

2.9 列表与key

在React中渲染列表时,需要为每个列表项提供一个唯一的key。key帮助React识别哪些元素发生了变化,从而 进步渲染效率。

2.9.1 渲染列表
function NumberList(props) { const numbers = props.numbers; const listItems = numbers. p((number) => <li key={number.toString()}> {number} </li> ); return ( <ul>{listItems}</ul> ); }
2.9.2 key的最佳 操作

使用唯一标识:如果列表项有唯一ID,应使用它作为key 不要使用索引作为key:除非列表项永远不会重新排序或过滤 key只在兄弟节点之间需要唯一:不需要全局唯一

三、React Hooks

3.1 何是Hooks

Hooks是React 16.8引入的新特性,它允许在不编写class的情况下使用state和其他React特性。Hooks使函数组件更加强大,同时解决了类组件的一些 难题。

3.2 useState Hook

useState是最基本的Hook,用于在函数组件中添加state。

3.2.1 基本用法
import React, { useState } from 'react'; function Counter() { // 声明一个名为count的state变量,初始值为0 const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
3.2.2 多个state变量
function Form() { // 声明多个state变量 const [name, setName] = useState(''); const [e il, setE il] = useState(''); const [age, setAge] = useState(18); return ( <form> <input type="text" value={name} onChange={(e) => setName(e.target.value)} /> <input type="e il" value={e il} onChange={(e) => setE il(e.target.value)} /> <input type="number" value={age} onChange={(e) => setAge(Number(e.target.value))} /> </form> ); }

3.3 useEffect Hook

useEffect用于在函数组件中执行副 影响操作,如数据获取、订阅、DOM操作等。它类似于类组件中的componentDidMount、componentDidUpdate和componentWillUnmount的组合。

3.3.1 基本用法
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); // 相当于componentDidMount和componentDidUpdate useEffect(() => { // 更新文档 深入了解 document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
3.3.2 条件执行

可以通过传递第二个参数来控制useEffect的执行条件:

// 仅在count变化时执行 useEffect(() => { document.title = `You clicked ${count} times`; }, [count]); // 仅在组件挂载时执行一次 useEffect(() => { // 订阅逻辑 const subscription = props.source.subscribe(); // 清理函数,在组件卸载时执行 return () => { subscription.unsubscribe(); }; }, []);

3.4 useContext Hook

useContext用于在函数组件中使用React上下文(Context),避免了组件间逐层传递props的 难题。

3.4.1 创建和使用Context
// 创建Context const ThemeContext = React.createContext('light'); function App() { return ( // 提供Context值 <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar() { return ( <div> <ThemedButton /> </div> ); } function ThemedButton() { // 使用useContext获取Context值 const theme = useContext(ThemeContext); return ( <button style={ { backgroundColor: theme }}> I am styled by theme context! </button> ); }

3.5 useReducer Hook

useReducer是useState的替代方案,适合管理复杂的state逻辑。它接收一个reducer函数,并返回当前state和dispatch 技巧。

3.5.1 基本用法
// 定义reducer函数 const initialState = { count: 0 }; function reducer(state, action) { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; case 'reset': return initialState; default: throw new Error(); } } function Counter() { // 使用useReducer const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} <button onClick={() => dispatch({ type: 'increment' })}>+</button> <button onClick={() => dispatch({ type: 'decrement' })}>-</button> <button onClick={() => dispatch({ type: 'reset' })}>Reset</button> </> ); }

3.6 useCallback Hook

useCallback用于缓存函数,避免在每次渲染时创建新的函数实例,从而优化子组件的性能。

3.6.1 基本用法
function ParentComponent() { const [count, setCount] = useState(0); // 使用useCallback缓存函数 const handleClick = useCallback(() => { console.log('Clicked with count:', count); }, [count]); // 只有count变化时才会重新创建函数 return ( <ChildComponent onClick={handleClick} /> ); }

3.7 useMemo Hook

useMemo用于缓存计算 结局,避免在每次渲染时进行重复计算,从而优化性能。

3.7.1 基本用法
function Example() { const [count, setCount] = useState(0); const [todos, setTodos] = useState([]); // 使用useMemo缓存计算 结局 const calculation = useMemo(() => { return expensiveCalculation(count); }, [count]); // 只有count变化时才会重新计算 return ( <div> <p>Count: {count}</p> <p>Calculation: {calculation}</p> <button onClick={() => setCount(count + 1)}>+</button> </div> ); }

3.8 useRef Hook

useRef用于在函数组件中保存可变值,或获取DOM节点的引用。

3.8.1 基本用法
function TextInputWithFocusButton() { // 创建ref const inputEl = useRef(null); const onButtonClick = () => { // 获取DOM节点并调用focus 技巧 inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text" /> <button onClick={onButtonClick}>Focus the input</button> </> ); }
3.8.2 保存可变值
function Timer() { const intervalRef = useRef(null); const [count, setCount] = useState(0); useEffect(() => { intervalRef.current = setInterval(() => { setCount(prevCount => prevCount + 1); }, 1000); return () => clearInterval(intervalRef.current); }, []); return ( <div> Seconds: {count} <button onClick={() => clearInterval(intervalRef.current)}> Stop </button> </div> ); }

3.9 自定义Hook

自定义Hook是一种复用 情形逻辑的方式,它允许你提取组件逻辑到可重用的函数中。

3.9.1 自定义Hook示例
// 自定义Hook:跟踪鼠标位置 function useMousePosition() { const [position, setPosition] = useState({ x: 0, y: 0 }); useEffect(() => { const handleMouseMove = (e) => { setPosition({ x: e.clientX, y: e.clientY }); }; window.addEventListener('mousemove', handleMouseMove); return () => { window.removeEventListener('mousemove', handleMouseMove); }; }, []); return position; } // 使用自定义Hook function DisplayMousePosition() { const position = useMousePosition(); return ( <div> Mouse position: {position.x}, {position.y} </div> ); }

四、React Router

4.1 何是React Router

React Router是React官方的路由库,用于处理单页应用(SPA)中的路由逻辑。它提供了声明式的路由定义方式,使开发者能够轻松构建具有复杂导航结构的应用。

4.2 React Router的基本概念

路由(Route):定义URL路径与组件之间的映射关系 路由匹配(Route Matching):根据当前URL找到匹配的路由 导航(Navigation):在不同路由之间切换的机制 路由参数(Route Parameters):从URL中提取动态数据

4.3 React Router的基本用法

4.3.1 安装React Router
npm install react-router-dom
4.3.2 基本路由配置
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'; function App() { return ( <Router> <div> <nav> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/about">About</Link></li> <li><Link to="/users">Users</Link></li> </ul> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/users" element={<Users />} /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; } function Users() { return <h2>Users</h2>; }

4.4 路由参数

路由参数允许从URL中提取动态数据,例如用户ID、产品ID等。

import { BrowserRouter as Router, Routes, Route, Link, useParams } from 'react-router-dom'; function App() { return ( <Router> <div> <nav> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/users/1">User 1</Link></li> <li><Link to="/users/2">User 2</Link></li> </ul> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/users/:id" element={<User />} /> </Routes> </div> </Router> ); } function User() { // 使用useParams获取路由参数 const { id } = useParams(); return <h2>User ID: {id}</h2>; }

4.5 嵌套路由

React Router支持嵌套路由,允许在组件内部定义子路由。

import { BrowserRouter as Router, Routes, Route, Link, Outlet } from 'react-router-dom'; function App() { return ( <Router> <div> <nav> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/topics">Topics</Link></li> </ul> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/topics" element={<Topics />}> <Route path="" element={<h3>Please select a topic.</h3>} /> <Route path=":topicId" element={<Topic />} /> </Route> </Routes> </div> </Router> ); } function Topics() { return ( <div> <h2>Topics</h2> <nav> <ul> <li><Link to="rendering">Rendering with React</Link></li> <li><Link to="components">Components</Link></li> <li><Link to="props-v-state">Props v. State</Link></li> </ul> </nav> {/* 嵌套路由的出口 */} <Outlet /> </div> ); } function Topic() { const { topicId } = useParams(); return <h3>Requested topic ID: {topicId}</h3>; }

4.6 导航

React Router提供了多种导航方式,包括:

Link组件:声明式导航 useNavigate Hook:编程式导航

import { BrowserRouter as Router, Routes, Route, Link, useNavigate } from 'react-router-dom'; function App() { return ( <Router> <div> <nav> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/dashboard">Dashboard</Link></li> </ul> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/login" element={<Login />} /> </Routes> </div> </Router> ); } function Login() { // 使用useNavigate进行编程式导航 const navigate = useNavigate(); const handleLogin = () => { // 模拟登录逻辑 // 登录成功后导航到dashboard navigate('/dashboard'); }; return ( <div> <h2>Login</h2> <button onClick={handleLogin}>Login</button> </div> ); }

4.7 路由守卫

路由守卫用于控制用户对某些路由的访问权限,例如验证用户是否已登录。

import { BrowserRouter as Router, Routes, Route, Navigate, useLocation } from 'react-router-dom'; function App() { return ( <Router> <Routes> <Route path="/" element={<Home />} /> <Route path="/login" element={<Login />} /> <Route path="/dashboard" element={<ProtectedRoute />}> <Route index element={<Dashboard />} /> <Route path="settings" element={<Settings />} /> </Route> </Routes> </Router> ); } // 模拟用户是否已登录 const isAuthenticated = () => { return localStorage.getItem('token') !== null; }; // 受保护的路由组件 function ProtectedRoute() { const location = useLocation(); if (!isAuthenticated()) { // 未登录,重定向到登录页 return <Navigate to="/login" state={ { from: location }} replace />; } return <Outlet />; }

五、 情形管理

5.1 何故需要 情形管理

在React应用中,随着组件层级的增加和复杂度的 进步, 情形管理变得越来越困难。主要挑战包括:

情形共享: 怎样在不同组件间共享 情形 情形更新: 怎样协调多个组件对同一 情形的更新 情形持久化: 怎样在页面刷新后保留 情形 情形调试: 怎样跟踪 情形变化

5.2 本地 情形管理

对于简单的应用,可以使用React内置的 情形管理机制:

useState:管理函数组件的本地 情形 useReducer:管理复杂的 情形逻辑 Context API:在组件树中共享 情形

5.3 Context API

Context API允许你在不通过props层层传递的情况下,在组件树中共享 情形。

5.3.1 创建和使用Context
// 创建Context const UserContext = React.createContext(); function App() { const [user, setUser] = useState({ name: 'Guest' }); return ( // 提供Context值 <UserContext.Provider value={ { user, setUser }}> <div> <Header /> <MainContent /> </div> </UserContext.Provider> ); } // 深层嵌套的组件可以直接使用Context function Profile() { const { user } = useContext(UserContext); return ( <div> <h2>Profile</h2> <p>Name: {user.name}</p> </div> ); }

5.4 Redux

Redux 一个流行的 情形管理库,遵循单向数据流和纯函数的 制度,使 情形变化可预测且易于调试。

5.4.1 Redux的核心概念

Store:应用的单一数据源,存储整个应用的 情形 Action:描述 情形变化的对象,包含type和payload Reducer:纯函数,接收当前 情形和action,返回新的 情形 Dispatch:触发action的 技巧

5.4.2 Redux的基本用法
// 安装Redux和React-Redux npm install redux react-redux // 定义action类型 const INCREMENT = 'INCREMENT'; const DECREMENT = 'DECREMENT'; // 定义action创建函数 const increment = () => ({ type: INCREMENT }); const decrement = () => ({ type: DECREMENT }); // 定义reducer const counterReducer = (state = { value: 0 }, action) => { switch (action.type) { case INCREMENT: return { value: state.value + 1 }; case DECREMENT: return { value: state.value - 1 }; default: return state; } }; // 创建store const store = createStore(counterReducer); // 使用Provider将store提供给整个应用 function App() { return ( <Provider store={store}> <Counter /> </Provider> ); } // 使用useSelector和useDispatch Hook连接组件和store function Counter() { const count = useSelector(state => state.value); const dispatch = useDispatch(); return ( <div> <p>Count: {count}</p> <button onClick={() => dispatch(increment())}>+</button> <button onClick={() => dispatch(decrement())}>-</button> </div> ); }

5.5 Redux Toolkit

Redux Toolkit是官方推荐的简化Redux开发的工具集,它解决了Redux的一些样板代码 难题。

5.5.1 Redux Toolkit的基本用法
// 安装Redux Toolkit npm install @reduxjs/toolkit // 创建slice const counterSlice = createSlice({ name: 'counter', initialState: { value: 0 }, reducers: { increment: (state) => { // 可以直接修改state, 由于Redux Toolkit使用immer state.value += 1; }, decrement: (state) => { state.value -= 1; }, incrementByAmount: (state, action) => { state.value += action.payload; } } }); // 导出action创建函数 export const { increment, decrement, incrementByAmount } = counterSlice.actions; // 创建store const store = configureStore({ reducer: { counter: counterSlice.reducer } });

5.6 MobX

MobX是另一个流行的 情形管理库,它基于响应式编程原理,使 情形变化自动反映在UI中。

5.6.1 MobX的基本概念

Observable State:可观察的 情形 Computed Values:从observable派生的计算值 Reactions:响应 情形变化的副 影响 Actions:修改 情形的函数

5.6.2 MobX的基本用法
// 安装MobX和MobX-React npm install mobx mobx-react // 创建store class CounterStore { @observable count = 0; @action increment = () => { this.count += 1; } @action decrement = () => { this.count -= 1; } @computed get doubleCount() { return this.count * 2; } } // 创建store实例 const counterStore = new CounterStore(); // 使用Provider提供store function App() { return ( <Provider counterStore={counterStore}> <Counter /> </Provider> ); } // 使用inject和observer连接组件和store @inject('counterStore') @observer class Counter extends React.Component { render() { const { counterStore } = this.props; return ( <div> <p>Count: {counterStore.count}</p> <p>Double Count: {counterStore.doubleCount}</p> <button onClick={counterStore.increment}>+</button> <button onClick={counterStore.decrement}>-</button> </div> ); } }

六、React性能优化

6.1 性能优化的重要性

随着应用规模的增长,性能 难题可能会变得越来越明显。优化React应用的性能可以:

进步用户体验,减少等待 时刻 降低资源消耗, 进步应用效率 支持更多用户并发访问 减少电池消耗,延长移动设备续航

6.2 虚拟DOM与Diff算法

React的虚拟DOM和Diff算法是其性能优化的基础。React通过比较新旧虚拟DOM的差异,只更新需要更新的 诚恳DOM部分。

6.3 使用shouldComponentUpdate 生活周期 技巧

在类组件中,可以通过实现shouldComponentUpdate 技巧来控制组件是否需要重新渲染:

class Counter extends React.Component { shouldComponentUpdate(nextProps, nextState) { // 只有当count变化时才重新渲染 return this.state.count !== nextState.count; } render() { return ( <div> <p>Count: {this.state.count}</p> <button onClick={this.increment}>+</button> </div> ); } }

6.4 使用React.memo

在函数组件中,可以使用React.memo来缓存组件,只有当props变化时才重新渲染:

const MyComponent = React.memo(function MyComponent(props) { // 只有当props变化时才会重新渲染 return ( <div> {props.name} </div> ); });

6.5 使用useMemo和useCallback

useMemo和useCallback可以分别缓存计算 结局和函数,避免在每次渲染时进行重复计算或创建新的函数实例:

function ParentComponent() { const [count, setCount] = useState(0); // 使用useCallback缓存函数 const handleClick = useCallback(() => { console.log('Clicked with count:', count); }, [count]); return ( <ChildComponent onClick={handleClick} /> ); } function ChildComponent({ onClick }) { // 使用useMemo缓存计算 结局 const expensiveValue = useMemo(() => { return expensiveCalculation(onClick); }, [onClick]); return ( <div> {expensiveValue} <button onClick={onClick}>Click</button> </div> ); }

6.6 代码分割

代码分割是一种将代码拆分为多个包的技术,可以减少初始加载 时刻。React提供了几种实现代码分割的方式:

6.6.1 使用React.lazy和Suspense
// 懒加载组件 const OtherComponent = React.lazy(() => import('./OtherComponent')); function MyComponent() { return ( <div> {/* 使用Suspense提供加载 情形 */} <React.Suspense fallback={<div>Loading...</div>}> <OtherComponent /> </React.Suspense> </div> ); }
6.6.2 路由级别代码分割
import { BrowserRouter as Router, Routes, Route, Suspense, Link } from 'react-router-dom'; // 懒加载路由组件 const Home = React.lazy(() => import('./Home')); const About = React.lazy(() => import('./About')); function App() { return ( <Router> <div> <nav> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/about">About</Link></li> </ul> </nav> <Suspense fallback={<div>Loading...</div>}> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </Suspense> </div> </Router> ); }

6.7 优化列表渲染

使用唯一key:帮助React识别哪些元素发生了变化 虚拟列表:对于大型列表,只渲染可见部分 列表项缓存:使用React.memo缓存列表项组件

function UserList({ users }) { // 使用React.memo缓存列表项组件 const UserItem = React.memo(({ user }) => ( <div> <p>Name: {user.name}</p> <p>E il: {user.e il}</p> </div> )); return ( <div> {users. p(user => ( // 使用唯一key <UserItem key={user.id} user={user} /> ))} </div> ); }

6.8 使用Profiler API

React 16.5引入了Profiler API,可以测量渲染一个React应用的成本:

<Profiler onRender={onRenderCallback}> <Navigation {...props} /> </Profiler>

6.9 使用Chrome DevTools分析性能

Chrome DevTools提供了React Profiler面板,可以可视化组件渲染、识别性能瓶颈:

打开Chrome DevTools 切换到”Profiler”面板 选择”Record”按钮 执行你想要分析的操作 停止记录并分析 结局

七、React生态 体系

7.1 流行的React库和工具

React拥有一个庞大的生态 体系, 下面内容是一些常用的库和工具:

情形管理:Redux、MobX、Zustand、Jotai 路由:React Router、Next.js 表单处理:Formik、React Hook Form 样式:Styled Components、Emotion、Tailwind CSS UI组件库:Material-UI、Ant Design、Chakra UI、React Bootstrap 测试:Jest、React Testing Library、Enzyme 数据获取:Axios、React Query、SWR 国际化:React Intl、i18next 动画:Framer Motion、React Spring

7.2 React与TypeScript集成

TypeScript是JavaScript的超集,提供了静态类型检查,可以显著 进步代码质量和开发效率。

7.2.1 安装TypeScript
npm install --save-dev typescript @types/react @types/react-dom
7.2.2 基本用法
// 定义接口 inte ce Props { name: string; age: number; isAdmin?: boolean; } // 函数组件 const User: React.FC<Props> = ({ name, age, isAdmin = false }) => { return ( <div> <p>Name: {name}</p> <p>Age: {age}</p> <p>Admin: {isAdmin ? 'Yes' : 'No'}</p> </div> ); }; // 类组件 class Counter extends React.Component< { initialCount: number }, // Props { count: number } // State > { constructor(props: { initialCount: number }) { super(props); this.state = { count: props.initialCount }; } increment = () => { this.setState(prevState => ({ count: prevState.count + 1 })); }; render() { return ( <div> <p>Count: {this.state.count}</p> <button onClick={this.increment}>+</button> </div> ); } }

7.3 React与Next.js

Next.js 一个基于React的服务器端渲染(SSR)框架,提供了开箱即用的路由、代码分割、静态生成等功能。

7.3.1 基本用法
npx create-next-app my-app cd my-app npm run dev
7.3.2 页面路由

Next.js使用文件 体系作为路由,pages目录下的每个文件都会自动成为一个路由:

// pages/index.js function HomePage() { return <div>Welcome to Next.js!</div>; } export default HomePage; // pages/users/[id].js function UserPage({ query }) { return <div>User ID: {query.id}</div>; } export default UserPage;

7.4 React与Gat y

Gat y 一个基于React的静态网站生成器,专注于性能和开发者体验。

7.4.1 基本用法
npx gat y new my-gat y-site cd my-gat y-site gat y develop
7.4.2 页面和组件
// src/pages/index.js import React from "react" import { Link } from "gat y" const IndexPage = () => { return ( <div> <h1>Hello Gat y!</h1> <Link to="/about/">About</Link> </div> ) } export default IndexPage

7.5 React Native

React Native允许使用React构建原生移动应用,实现”一次编写,多平台运行”。

7.5.1 基本用法
npx react-native init MyApp cd MyApp npx react-native run-android # 或 npx react-native run-ios
7.5.2 基本组件
import React, { useState } from 'react'; import { Button, Text, View, StyleSheet } from 'react-native'; const App = () => { const [count, setCount] = useState(0); return ( <View style={styles.container}> <Text>You clicked {count} times</Text> <Button onPress={() => setCount(count + 1)} title="Click me" /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', paddingHorizontal: 10 } }); export default App;

八、 拓展资料

React作为当今最流行的前端框架 其中一个,以其组件化、声明式和高效的特性,帮助开发者构建复杂的Web应用。 这篇文章小编将从React的基本概念、核心特性、 情形管理、性能优化到生态 体系,全面介绍了React的各个方面。对于前端开发者来说,掌握React不仅能提升个人技能,还能为开发高质量的Web应用提供强大支持。 最后附上官网 进修地址:https://react.docschina.org/learn