React 18 系统精讲 结合TS打造旅游电商平台(高の青)

2024-07-10 10:39:48 浏览数 (2)

React 18 是 Facebook 推出的 JavaScript 库 React 的最新版本,带来了许多新功能和改进。

React 18 的主要特性

1.1 并发模式 (Concurrent Mode)

并发模式是 React 18 的核心功能之一,旨在提升应用的响应速度和用户体验。并发模式允许 React 在后台准备多个 UI 更新,而不会阻塞主线程。这样,当主线程空闲时,可以迅速切换到这些预准备的更新上,从而减少用户界面的卡顿现象。

并发模式的主要特性包括:

  • 自动批处理 (Automatic Batching):在 React 18 中,多个状态更新可以自动批处理,从而减少不必要的渲染次数,提高性能。
  • 可中断渲染 (Interruptible Rendering):React 可以在渲染过程中暂停当前任务,处理更高优先级的任务,然后继续之前的任务。这使得 UI 更加流畅和响应快速。
  • 优先级调度 (Priority Scheduling):React 18 引入了优先级调度机制,根据任务的重要性和紧急程度,合理分配资源,从而优化用户体验。

1.2 自动批处理 (Automatic Batching)

在 React 18 之前,状态更新通常会触发多次渲染。而在 React 18 中,自动批处理功能可以将多个状态更新合并为一个渲染,从而减少渲染次数,提高性能。

代码语言:txt复制
// 之前版本
function handleClick() {
  setCount(count   1);
  setFlag(true);
  // 这将导致两次重新渲染
}

// React 18
function handleClick() {
  setCount(count   1);
  setFlag(true);
  // 这只会导致一次重新渲染
}

1.3 并发渲染 API

React 18 引入了一些新的 API 来支持并发渲染:

  • startTransition:标记非紧急更新,使其在资源允许时进行渲染。
  • useTransition:用于管理并发状态更新,提供挂起状态和过渡状态。
  • useDeferredValue:推迟计算代价高昂的值,提升应用性能。
代码语言:txt复制
import { useTransition } from 'react';

function App() {
  let [isPending, startTransition] = useTransition();

  function handleClick() {
    startTransition(() => {
      setCount(count   1);
    });
  }

  return (
    <div>
      {isPending ? "Loading..." : count}
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

1.4 新的 SSR 改进

React 18 对服务器端渲染 (SSR) 也进行了显著改进,提升了性能和用户体验:

  • 流式渲染 (Streaming Rendering):允许服务器逐步向客户端发送 HTML,从而提高首屏渲染速度。
  • 服务器组件 (Server Components):服务器组件是可以在服务器端渲染的 React 组件,能够减少客户端的 JavaScript 负载。

下面是一个简单的步骤说明和代码示例, React 18 和 TypeScript 创建一个基本的旅游电商平台。

React 18 TypeScript 打造旅游电商平台

项目初始化

  • 创建新项目
代码语言:txt复制
npx create-react-app travel-ecommerce --template typescript
cd travel-ecommerce
  • 安装必要的依赖
代码语言:txt复制
npm install react-router-dom @types/react-router-dom

项目结构

创建如下项目结构:

代码语言:txt复制
src/
|-- components/
|   |-- ProductCard.tsx
|-- pages/
|   |-- HomePage.tsx
|   |-- ProductListPage.tsx
|   |-- ProductDetailPage.tsx
|-- App.tsx
|-- index.tsx
|-- types/
|   |-- index.ts

定义类型

src/types/index.ts 文件中定义产品类型:

代码语言:txt复制
export interface Product {
    id: number;
    name: string;
    description: string;
    price: number;
    imageUrl: string;
}

创建组件

ProductCard 组件 (src/components/ProductCard.tsx):

代码语言:txt复制
import React from 'react';
import { Product } from '../types';

interface ProductCardProps {
    product: Product;
}

const ProductCard: React.FC<ProductCardProps> = ({ product }) => {
    return (
        <div className="product-card">
            <img src={product.imageUrl} alt={product.name} />
            <h3>{product.name}</h3>
            <p>{product.description}</p>
            <p>${product.price}</p>
        </div>
    );
};

export default ProductCard;

 

HomePage 组件 (src/pages/HomePage.tsx):

代码语言:txt复制
import React from 'react';
import { Link } from 'react-router-dom';

const HomePage: React.FC = () => {
    return (
        <div>
            <h1>Welcome to Travel Ecommerce</h1>
            <Link to="/products">View Products</Link>
        </div>
    );
};

export default HomePage;

ProductListPage 组件 (src/pages/ProductListPage.tsx):

代码语言:txt复制
import React from 'react';
import ProductCard from '../components/ProductCard';
import { Product } from '../types';

const products: Product[] = [
    { id: 1, name: 'Tour Package 1', description: 'Amazing tour package', price: 499, imageUrl: 'https://via.placeholder.com/150' },
    // 添加更多产品
];

const ProductListPage: React.FC = () => {
    return (
        <div>
            <h2>Products</h2>
            <div className="product-list">
                {products.map(product => (
                    <ProductCard key={product.id} product={product} />
                ))}
            </div>
        </div>
    );
};

export default ProductListPage;

ProductDetailPage 组件 (src/pages/ProductDetailPage.tsx):

代码语言:txt复制
import React from 'react';
import { useParams } from 'react-router-dom';
import { Product } from '../types';

const products: Product[] = [
    { id: 1, name: 'Tour Package 1', description: 'Amazing tour package', price: 499, imageUrl: 'https://via.placeholder.com/150' },
    // 添加更多产品
];

const ProductDetailPage: React.FC = () => {
    const { id } = useParams<{ id: string }>();
    const product = products.find(p => p.id === Number(id));

    if (!product) {
        return <div>Product not found</div>;
    }

    return (
        <div>
            <h2>{product.name}</h2>
            <img src={product.imageUrl} alt={product.name} />
            <p>{product.description}</p>
            <p>${product.price}</p>
        </div>
    );
};

export default ProductDetailPage;

设置路由

src/App.tsx 文件中设置路由:

代码语言:txt复制
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import HomePage from './pages/HomePage';
import ProductListPage from './pages/ProductListPage';
import ProductDetailPage from './pages/ProductDetailPage';

const App: React.FC = () => {
    return (
        <Router>
            <Routes>
                <Route path="/" element={<HomePage />} />
                <Route path="/products" element={<ProductListPage />} />
                <Route path="/products/:id" element={<ProductDetailPage />} />
            </Routes>
        </Router>
    );
};

export default App;

启动项目

运行以下命令启动项目:

代码语言:txt复制
npm start

0 人点赞