网站首页 > 技术文章 正文
大家好,我是Echa。
好消息,2023年10月26号Next.js 官方研发团队Lee Robinson 和Tim Neutkens一起对外宣布Next.js 14 正式发布。距离上一个Next.js 13.5 版本(2023年9月19日),只用了短短37 天时间,而且直接跨越式从 Next.js 13.5 跳到 14版本,从侧面说明了Next.js 研发团队技术实力非常不错的,但其Github仓库的 star 数已超过 114k,并且在全球拥有超过 114w名用户。Next.js 官方研发团队真厉害,给咱们开发人员带来了很多方便,小编举起大拇指点赞。
但是又会有人说前端太卷了,根本学不过来;还有人会说各自为了完成KPI;粉丝们你们怎么看呢?欢迎在评论下说出自己的看法。
借此机会,小编先给大家详细介绍一下Next.js 到底是什么,能做什么,有哪些优点等等,只有彻底了解了Next.js ,才能说出自己观点。希望对大家有所帮助,多了解,多学点有益无害,说不定哪天团队开发项目中就用上,你说是不是?下面小编给大家一一介绍上面的问题。
全文大纲
- Next.js 介绍
- 为什么选择 Next.js ?
- Next.js 有哪些优势呢?
- Next.js 渲染方式有哪些?
- 手把手教你搭建属于自己的Next.js 项目
- Next.js 14发布了哪些内容呢?
Next.js 介绍
传送门:https://nextjs.org/
Github:https://github.com/vercel/next.js
Next.js是一个流行的React框架,为开发人员提供了许多有用的功能和便利,用于构建现代化、可扩展的Web应用程序,用于构建React应用程序。它在React的基础上提供了一些增强功能,包括服务器渲染(SSR)、静态生成(SSG)、路由等。Next.js的目标是简化React应用程序的开发流程,并提供更好的性能。
Next.js 为您提供生产环境所需的所有功能以及最佳的开发体验:包括静态及服务器端融合渲染、 支持 TypeScript、智能化打包、 路由预取等功能无需任何配置。
为什么选择 Next.js ?
因为全球领先的公司都在使用并喜爱 Next.js。
选择 Next.js原因如下:
- 零配置
自动编译并打包。从一开始就为生产环境而优化。
- 混合模式: SSG 和 SSR
在一个项目中同时支持构建时预渲染页面(SSG)和请求时渲染页面(SSR)。
- 增量静态生成
在构建之后以增量的方式添加并更新静态预渲染的页面。
- 支持 TypeScript
自动配置并编译 TypeScript。
- 快速刷新
快速、可靠的实时编辑体验,已在 Facebook 级别的应用上规模上得到验证。
- 基于文件系统的路由
每个 pages 目录下的组件都是一条路由。
- API路由
创建 API 端点(可选)以提供后端功能。
- 内置支持CSS
使用 CSS 模块创建组件级的样式。内置对 Sass 的支持。
- 代码拆分和打包
采用由 Google Chrome 小组创建的、并经过优化的打包和拆分算法。
小编描述了这么多,不如直接上图:
Next.js官网描述是:这是一个用于生产环境的React框架,对这句话的理解得关注这两个关键词:
生产环境:能用于生产就得考虑到方方面面功能,比如性能怎么保证、SSR/CSR/SSG等渲染机制的支持、打包、路由支持、css module,对开发环境的友好,是否能内置支持TypeScript,配置方面也尽可能简化
React框架:所以Next.js是基于React开发,跟Vue和Angular无关。
要从头开始使用 React 构建一个完整的 Web 应用程序,需要考虑许多重要的细节:
- 必须使用打包程序(例如 webpack)打包代码,并使用 Babel 等编译器进行代码转换。
- 你需要针对生产环境进行优化,例如代码拆分。
- 你可能需要对一些页面进行预先渲染以提高页面性能和 SEO。你可能还希望使用服务器端渲染或客户端渲染。
- 你可能必须编写一些服务器端代码才能将 React 应用程序连接到数据存储。
一个框架就可以解决上述这些问题。但是,这样的框架必须具有正确的抽象级别,否则它将不是很有用。它还需要具有出色的“开发人员体验”,以确保您和您的团队在编写代码时拥有出色的体验。
Next.js 有哪些优势呢?
Next.js 官方案例提供了周边框架的搭建案例,方便开发者配置相关框架和插件,具体如下:
前面内容小编也有提到了Next.js 优势,具体如下:
- 零配置:无需配置webpack、babel等工具,只需安装next、react和react-dom即可开始开发。
- 路由系统:无需使用第三方库,只需在pages目录下创建文件或文件夹,即可实现动态路由和嵌套路由。
- 代码分割:自动对每个页面进行代码分割,优化性能和加载速度。
- 预渲染:可以选择使用SSR或SSG来预渲染页面,提高SEO和用户体验。
- API路由:可以在pages/api目录下创建API路由,处理各种后端逻辑。
- 插件系统:可以使用各种插件来扩展Next.js的功能,如图片优化、国际化、数据获取等。
完善的工程化机制
你不需要自己去配置 webpack 方案,它已经内置了以下工程化基础:
- babel 内置,支持JS代码向后兼容
- postcss 内置,支持CSS代码向后兼容
- browserslist 支持配置兼容的浏览器信息,配合 babel 和 postcss 工作。
- TypeScript 可选择使用,保证代码的质量,以及可阅读性和可维护性。
- eslint 可选择使用,检测代码格式,可自定义规则。vscode 编写代码,或者build打包时都会有提示。
- prettier 可通过扩展使用,格式化代码,可自定义规则。
- css modules 内置
- css-in-js 可扩展使用
- tailwind css 可扩展使用
也做了一些打包优化功能:
- tree shaking
- 代码压缩
- 页面自动静态化
- 按需打包第三方 es 包(通过设置 transpilePackages 属性,让部分包可以被 next-babel 打包)
- 异步动态加载组件,和 React.lazy 功能一样,只不过实现得更早。
Next.js 渲染方式有哪些?
Next.js 渲染方法总共分四种:客户端渲染(CSR)、服务器端渲染(SSR)、静态站点生成(SSG)和增量静态生成(ISR)。
渲染是将React代码转换成HTML的过程。用户选择的渲染方法取决于所处理的数据以及用户对性能的关注程度。
在Next.js中,渲染的用途非常广泛。用户可以用静态或增量方式渲染客户端或服务器端页面。
小编让大家看看这些方法是如何工作的以及每种方法有怎样的表现。具体如下:
客户端渲染(CSR)
当用户需要频繁更新数据或不想预渲染页面时,应该使用客户端渲染(CSR)。用户可以在页面层面或组件层面实现CSR。在页面层面,Next.js在运行时获取数据;而在组件层面执行操作时,它在页面挂载时获取数据。正因为如此,CSR可能导致性能变慢。
使用useEffect()钩子在客户端渲染页面,如下所示:
import { useState, useEffect } from 'react'
function Home() {
const [data, setData] = useState(null)
const [isLoading, setLoading] = useState(false)
useEffect(() => {
setLoading(true)
fetch('/api/get-data')
.then((res) => res.json())
.then((data) => {
setData(data)
setLoading(false)
})
}, [])
if (isLoading) return <p>Loading...</p>
if (!data) return <p>No data</p>
return (
<div>
// Use data
</div>
)
}
还可以使用SWR钩子。它缓存数据,一旦数据过时,就重新验证数据。
import useSWR from 'swr'
const fetcher = (...args) => fetch(...args).then((res) => res.json())
function Home() {
const { data, error } = useSWR('/api/data', fetcher)
if (error) return <div>Failed to load</div>
if (!data) return <div>Loading...</div>
return (
<div>
// Use data
</div>
)
}
在Next.js 13中,用户需要使用客户端组件,为此在文件顶部添加“use client”指令。
"use client";
export default () => {
return (
<div>
// Client component
</div>
);
};
SSR和CSR的区别在于,在SSR中,从服务器上的每个页面请求获取数据;而在CSR中,从客户端获取数据。
服务器端渲染(SSR)
就服务器端渲染(SSR)而言,当用户访问网页时,浏览器向服务器发送关于该页面的请求。服务器从数据库获取必要的数据(如果需要的话),并将其与页面内容一同发送到浏览器。然后浏览器将其显示给用户。
浏览器对用户点击的每个链接发出此请求,这意味着服务器每次都处理请求。这可能会降低网站的性能。然而,服务器端渲染非常适合使用动态数据的页面。
每当用户请求时,使用getServerSideProps重新构建页面。
export default function Home({ data }) {
return (
<main>
// Use data
</main>
);
}
export async function getServerSideProps() {
// Fetch data from external api
const res = await fetch('https://.../data')
const data = await res.json()
// Will be passed to the page component as props
return { props: { data } }
}
getServerSideProps只在服务器上运行,它是这样运行的:
- 当用户直接访问页面时,它在请求时运行,页面使用它返回的属性来预渲染。
- 当用户通过Next链接访问页面时,浏览器向运行它的服务器发送请求。
在新版本中,用户可以选择使用页面或布局中的动态数据获取来享用服务器端渲染。
动态数据获取是fetch()请求,它通过将缓存选项设置为“no-store”来选择退出缓存。
fetch (https://..。', {cache: 'no-store'});
或者,将revalidate设置为0:
fetch (https://..。', {next: {revalidate: 0}});
静态站点生成(SSG)
就静态站点生成(SSG)而言,页面在构建期间只获取一次数据。静态生成页面非常快,性能良好,因为所有页面都事先构建。SSG因此非常适合使用静态内容(比如销售页面或博客)的页面。
在Next.js中,用户必须从想要静态渲染的页面中导出 getStaticProps函数。
export default function Home({ data }) {
return (
<main>
// Use data
</main>
);
}
export async function getStaticProps() {
// Fetch data from external API at build time
const res = await fetch('https://.../data')
const data = await res.json()
// Will be passed to the page component as props
return { props: { data } }
}
用户还可以在getStaticProps里面查询数据库。
export async function getStaticProps() {
// Call function to fetch data from database
const data = await getDataFromDB()
return { props: { data } }
}
在Next.js 13中,静态渲染是默认操作,内容被获取和缓存,除非用户关闭了缓存选项。
async function getData() {
const res = await fetch('https://.../data');
return res.json();
}
export default async function Home() {
const data = await getData();
return (
<main>
// Use data
</main>
);
}
增量静态生成(ISR)
有时用户想使用SSG,但又想定期更新内容,这时候增量静态生成(ISG)大有帮助。
ISG让用户可以在构建静态页面后在指定的时间间隔后创建或更新静态页面。这样一来,用户不需要重建整个站点,只需重建需要它的页面。
ISG保留了SSG的优点,又增加了为用户提供最新内容的好处。ISG非常适合站点上那些使用不断变化的数据的页面。比如说,用户可以使用ISR渲染博文,以便在编辑文章或添加新文章后博客保持更新。
若要使用ISR,将revalidate属性添加到页面上的getStaticProps函数中。
export async function getStaticProps() {
const res = await fetch('https://.../data')
const data = await res.json()
return {
props: {
data,
},
revalidate: 60
}
}
在这里,当请求在60秒后到来时,Next.js将尝试重新构建页面。下一个请求将产生带有更新页面的响应。
在Next.js 13中,使用fetch中的revalidate,就像这样:
fetch (https://..。/data', {next: {revalidate: 60}});
用户可以将时间间隔设置为最适合其数据的任何时间间隔。
如何选择渲染方法?
到目前为止,用户已了解了Next.js中的四种渲染方法:CSR、SSR、SSG和ISG。每种方法都适用于不同的情况。CSR适用于需要新数据的页面。SSR适用于使用动态数据的页面,但它对SEO较为友好。
SSG适合数据基本上静态的页面,而ISG最适合含有用户想要间隔更新的数据的页面。SSG和ISG从性能和SEO方面来说都很出色,因为数据预获取,用户还可以缓存数据。
手把手教你搭建属于自己的Next.js 项目
系统环境需求
- Node.js 12.22.0 或更高版本
- MacOS、Windows (包括 WSL) 和 Linux 都被支持
安装设置
我们建议使用 create-next-app创建新的 Next.js 应用程序,它会自动为你设置所有内容。创建项目,请运行:
npx create-next-app@latest
# or
yarn create next-app
如果你希望使用 TypeScript 开发项目,可以通过 --typescript 参数创建 TypeScript 项目:
npx create-next-app@latest --typescript
# or
yarn create next-app --typescript
安装完成后:
- 运行 npm run dev 或 yarn dev 来启动开发服务器,访问地址为 http://localhost:3000。
- 通过 http://localhost:3000 地址访问你的应用程序。
- 编辑 pages/index.js 文件并在浏览器中查看更新。
手动安装设置
为你的项目安装 next、react 和 react-dom :
npm install next react react-dom
# or
yarn add next react react-dom
打开 package.json 文件并添加 scripts 配置段:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
这些脚本涉及开发应用程序的不同阶段:
- dev - 运行 next dev,以开发模式启动 Next.js
- build - 运行 next build,以构建用于生产环境的应用程序
- start - 运行 next start,已启动 Next.js 生产环境服务器
- lint - 运行 next lint,以设置 Next.js 的内置 ESLint 配置
Next.js 是围绕着 页面(pages) 的概念构造的。一个页面(page)就是一个从 pages 目录下的 .js、.jsx、.ts 或 .tsx 文件导出的 React 组件。
页面(page) 根据其文件名与路由关联。例如,pages/about.js 被映射到 /about。甚至可以在文件名中添加动态路由参数。
在你的项目中创建一个 pages 目录。
为 ./pages/index.js 文件填充如下内容:
function HomePage() {
return <div>Welcome to Next.js!</div>
}
export default HomePage
到目前为止,我们得到了:
- 自动编译和打包(利用 webpack 和 babel)
- React 快速刷新
- ./pages/ 中的 静态生成和服务器端渲染
- 静态文件服务。./public/ 被映射到 /
此外,任何 Next.js 应用程序从一开始就是可以投入到生产环境中。
Next.js 14发布了哪些内容呢?
Next.js 14 官方正式发布该版本的主要更新如下:
- Turbopack:App & Pages Router 通过 5000 个测试
- 本地服务器启动速度提高了 53%
- 通过快速刷新,代码更新速度提高 94%
- 服务端操作(稳定):逐步增强的数据变更
- 集成了缓存和重新验证
- 简单的函数调用,或者与表单原生配合工作
- 部分预渲染(预览):快速的初始静态响应 + 流式动态内容
- Next.js Learn(全新):教授 App Router、身份验证、数据库等内容的免费课程。
可以通过以下命令来立即升级最新版本:
npx create-next-app@latest
Next.js 编译器
自 Next.js 13 发布以来,Next 团队一直致力于提高 Next.js 中 Pages 和 App Router 的本地开发性能。
之前,Next 团队通过重写 Next.js 的 next dev 和其他部分以实现这一目标。然而,后来改变了方法,采取了更渐进的方式。现在,重点是首先支持所有 Next.js 的功能,因此基于 Rust 的编译器很快就会稳定下来。
Next.js 使用基于 Rust 引擎的 Turbopack,现在已经通过了 5000 个 next dev 的集成测试。这些测试涵盖了过去 7 年中的错误修复和重现。
在大型 Next.js 应用 vercel.com 上进行测试时,可以看到:
- 本地服务器启动速度提高高达 53.3%
- 通过快速刷新,代码更新速度提高高达 94.7%
该基准测试是大型应用(和大型模块图)性能改进的实际结果。现在,next dev 的 90% 测试已经通过,在使用 next dev --turbo 时,应该会看到更快、更可靠的性能表现。
一旦达到 100% 的测试通过,将在即将发布的次要版本中将 Turbopack 移至稳定版本。另外,还将继续支持使用 webpack 进行自定义配置和生态系统插件。
可以在 areweturboyet.com 上关注通过测试的百分比。
表单和数据变更
Next.js 9 引入了 API Routes,这是一种快速构建后端端点的方法,可以与前端代码一起使用。
例如,可以在 api/ 目录中创建一个新文件:
//pages/api/submit.ts
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const data = req.body;
const id = await createItem(data);
res.status(200).json({ id });
}
然后,在客户端,可以使用 React 和 onSubmit 等事件处理程序来获取 API 路由:
//pages/index.tsx
import { FormEvent } from 'react';
export default function Page() {
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
});
// Handle response if necessary
const data = await response.json();
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
);
}
现在,随着 Next.js 14 的推出,希望简化开发者在编写数据变更时的体验。此外,还希望在用户网络连接较慢或从低功率设备提交表单时改善用户体验。
服务端操作(稳定)
如果不想手动创建 API Route,那么可以定义一个函数,在服务端安全地运行,并直接从 React 组件中调用它。
App Router 构建在 React canary 通道上,对于框架 采用新功能来说是稳定的。从 v14 开始,Next.js 已升级到最新的 React canary,其中包括稳定的服务器操作。
App Router 是建立在 React canary 通道上的,这个通道对于框架来采用新功能是稳定的。从 v14 开始,Next.js 已经升级到了最新的 React canary 版本,其中包含稳定的服务端操作功能。
前面 Pages Router 的例子可以简化为一个文件:
// app/page.tsx
export default function Page() {
async function create(formData: FormData) {
'use server';
const id = await createItem(formData);
}
return (
<form action={create}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
);
}
服务端操作对于之前使用过服务端中心框架的开发者来说应该会很熟悉。它是建立在 Web 基础知识(如表单和 FormData Web API)之上的。
通过表单使用服务端操作对于渐进增强是有帮助的,但并不是必需的。也可以直接将其作为函数调用,而无需使用表单。在使用 TypeScript 时,这提供了完整的端到端类型安全性,确保客户端和服务端之间的安全性。
数据变更、页面重新渲染或重定向可以在一次网络往返中完成,确保在客户端上显示正确的数据,即使上游提供者的响应速度较慢。此外,可以组合和重用不同的操作,包括在同一个路由中使用多个不同的操作。
缓存、重新验证、重定向等
服务端操作深度集成到整个 App Router 模型中。你可以:
- 使用 revalidatePath() 或 revalidateTag() 可以重新验证缓存的数据。
- 使用redirect()重定向到不同的路由。
- 使用cookies()设置和读取cookie
- 使用 useOptimistic() 处理乐观 UI 更新
- 使用 useFormState() 捕获并显示来自服务端的错误
- 使用 useFormStatus() 在客户端显示加载状态
部分预渲染(预览)
Next.js 中正在开发的部分预渲染推出了预览版,它是一种针对动态内容的编译器优化,可以实现快速的初始静态响应。
部分预渲染建立在对服务端渲染(SSR)、静态站点生成(SSG)和增量静态重新验证(ISR)进行了十年的研究和开发的基础上。
Motivation(动机)
目前存在过多的运行时、配置选项和渲染方法需要考虑。希望在享受静态网页的速度和可靠性的同时,也能支持完全动态、个性化的响应。不过,拥有出色的性能和个性化体验不应以复杂性为代价。
面临的挑战是创建更好的开发体验,简化现有模型,而无需引入新的需要学习的 API。虽然部分缓存服务端内容的方法已经存在,但这些方法仍然需要满足旨在实现的开发者体验和可组合性目标。
部分预渲染不需要学习新的 API。
建立在 React Suspense 之上
部分预渲染是由 Suspense 边界定义的。以下是它的工作原理。考虑以下电子商务页面:
// app/page.tsx
export default function Page() {
return (
<main>
<header>
<h1>My Store</h1>
<Suspense fallback={<CartSkeleton />}>
<ShoppingCart />
</Suspense>
</header>
<Banner />
<Suspense fallback={<ProductListSkeleton />}>
<Recommendations />
</Suspense>
<NewProducts />
</main>
);
}
启用部分预渲染后,该页面将根据 <Suspense /> 边界生成静态骨架,它包含了页面的结构和布局,但不包含动态内容。React Suspense 的fallback也会被预渲染。
然后,在静态骨架中,Suspense 的fallback将被动态组件替换,例如读取 cookie 来确定购物车内容,或者根据用户显示横幅广告。
当发出请求时,立即提供静态 HTML 骨架:
<main>
<header>
<h1>My Store</h1>
<div class="cart-skeleton">
<!-- Hole -->
</div>
</header>
<div class="banner" />
<div class="product-list-skeleton">
<!-- Hole -->
</div>
<section class="new-products" />
</main>
由于 <ShoppingCart /> 组件需要读取cookie以查看用户会话,因此该组件将作为同一HTTP请求的一部分进行流式传输,与静态骨架一起加载,这样就不需要额外的网络往返。
// app/cart.tsx
import { cookies } from 'next/headers'
export default function ShoppingCart() {
const cookieStore = cookies()
const session = cookieStore.get('session')
return ...
}
为了获得最细粒度的静态骨架,可能需要添加额外的 <Suspense /> 边界。然而,如果今天已经在使用 loading.js,那么这是一个隐式的 <Suspense /> 边界,因此不需要更改即可生成静态骨架。
即将到来
部分预渲染正在积极开发中,将在即将发布的次要版本中分享更多更新。
元数据改进
在页面内容从服务端流式传输之前,需要先向浏览器发送关于视口、颜色方案和主题等重要元数据。
确保这些meta标签与初始页面内容一起发送可以提供流畅的用户体验,防止由于更改主题颜色或视口变化而导致页面闪烁或布局偏移。
在 Next.js 14 中,将阻塞和非阻塞的元数据解耦。只有一小部分元数据选项是阻塞的,希望确保非阻塞的元数据不会阻止部分预渲染页面提供静态骨架。
以下元数据选项现已弃用,并将在未来的主要版本中从元数据中删除:
- viewport:设置视口的初始缩放和其他属性
- colorScheme:设置视口的支持模式(亮/暗)
- themeColor: 设置视口周围的浏览器界面应该呈现的颜色
从 Next.js 14 开始,使用新的选项 viewport 和 generateViewport 来替换这些选项。所有其他元数据选项保持不变。
Next.js Learn 课程
在 Next.js Learn 上发布了全新的免费课程。本课程教授:
- Next.js App Router
- 样式和 Tailwind CSS
- 优化字体和图像
- 创建布局和页面
- 在页面之间导航
- 设置 Postgres 数据库
- 使用服务端组件获取数据
- 静态和动态渲染
- 流媒体
- 部分预渲染(可选)
- 添加搜索和分页
- 数据变更
- 错误处理
- 改善无障碍环境
- 添加身份验证
- 添加元数据
其他更新
- [重大变更] 现在 Node.js 最低版本要求为 18.17
- [重大变更] 移除了 next-swc 构建的 WASM 目标
- [重大变更] 放弃支持 @next/font,转而支持 next/font
- [重大变更] 将 ImageResponse 导入从 next/server 更改为 next/og
- [重大变更] next export 命令已弃用,推荐使用 output: 'export'
- [弃用] next/image 的 onLoadingComplete 已弃用,推荐使用 onLoad
- [弃用] next/image 的 domains 已弃用,推荐使用 remotePatterns
- [功能] 可以启用更详细的关于获取缓存的日志记录
- [改进] 基本 create-next-app 应用的函数大小减小了 80%
最后
一行代码,可能会创造出下一个让人惊叹的产品;
一个创新,可能会开启一个全新的科技时代;
一份初心,可能会影响到无数人的生活;
无论是在大公司工作,还是在小团队奋斗;
无论是资深的程序员,还是刚刚入行的新手;
每个人的代码,都有力量改变世界。
创作不易,喜欢的老铁们加个关注,点个赞,打个赏,后面会不定期更新干货和技术相关的资讯,速速收藏,谢谢!你们的一个小小举动就是对小编的认可,更是创作的动力。
创作文章的初心是:沉淀、分享和利他。既想写给现在的你,也想贪心写给 10 年、20 年后的工程师们,现在的你站在浪潮之巅,面对魔幻的互联网世界,很容易把一条河流看成整片大海。未来的读者已经知道了这段技术的发展历史,但难免会忽略一些细节。如果未来的工程师们真的创造出了时间旅行机器,可以让你回到现在。那么小编的创作就是你和当年工程师们的接头暗号,你能感知到他们在这个时代的键盘上留下的余温。
猜你喜欢
- 2024-10-01 React状态管理专题:什么是Redux(react+redux)
- 2024-10-01 React:组件的生命周期(react组件的生命周期函数)
- 2024-10-01 react native 封装一个公用的数据请带上拉分页下拉刷新的组件
- 2024-10-01 React是一个前端开发项目的JavaScript库
- 2024-10-01 「最简教程」每天一篇,轻松搞定 React——状态提升
- 2024-10-01 千万级项目后台菜单导航设计及react antd实现
- 2024-10-01 这就是你日思夜想的 React 原生动态加载
- 2024-10-01 React 渲染的未来(react 渲染流程)
- 2024-10-01 React 最简单的入门应用项目(react简单吗)
- 2024-10-01 React热加载器(react的loading加载)
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)