创建项目

先创建个 Next.js 项目

pnpm create next-app --typescript

安装 react-router-dom

"dependencies": {

"next": "13.0.0",

"react": "18.2.0",

"react-dom": "18.2.0",

"react-router-dom": "^6.4.2"

},

"devDependencies": {

"@types/node": "18.11.6",

"@types/react": "18.0.23",

"@types/react-dom": "18.0.7",

"eslint": "8.26.0",

"eslint-config-next": "13.0.0",

"typescript": "4.8.4"

}

创建相关组件

创建路由组件 components\MyRouter.tsx 使用 Hash 路由

import { lazy } from "react";

import { RouterProvider, createHashRouter as createRouter } from "react-router-dom";

let Login = lazy(() => import("./Login"));

let Layout = lazy(() => import("./Layout"));

let Home = lazy(() => import("./Home"));

let Log = lazy(() => import("./Log"));

// 只是例子,随便写写

let router = createRouter([

{

path: "/login",

element: ,

loader: () => {

return "我是 loder data";

},

},

{

element: ,

children: [

{

path: "/",

element: ,

},

{

path: "/log",

element: ,

},

{

path: "*",

element: (

<>

error 404

),

},

],

},

]);

export default function MyRouter() {

return (

<>

);

}

创建组件 components\Layout\index.tsx 关键代码是 Suspense 与 Outlet

路由跳转 JSX 中使用 Link Hook 中使用 useNavigate react-router 相关请看官网,这里不再赘述.

import { FC, memo, Suspense } from "react";

import { Link, Outlet } from "react-router-dom";

interface IProps {}

let Index: FC = function (props) {

return (

<>

Layout\index.tsx

  • login

  • Home

  • log

);

};

export default memo(Index);

在 pages/index.tsx 中使用

在 pages/index.tsx 中使用 dynamic 导入 MyRouter , 并设置 ssr: false 使用 Suspense 包裹 MyRouter

import dynamic from "next/dynamic";

import { FC, memo, Suspense } from "react";

const MyRouter = dynamic(() => import("../components/MyRouter"), { ssr: false });

interface IProps {}

let Index: FC = function (props) {

return (

);

};

export default memo(Index);

处理 404 页面

创建页面 pages/404.tsx 访问除首页(/)外的地址时, Next.js 会进入到这个404页面, 这里使用 Next.js useRouter 将路由导航到首页 / (因为 404 页面是属于 Next.js 的路由页面, 不在 react-dom 的 RouterProvider 中)

import { useRouter } from "next/router";

import { FC, memo, useEffect } from "react";

interface IProps {}

let Index: FC = function () {

let router = useRouter();

useEffect(() => {

router.push("/");

}, [router]);

return <>;

};

export default memo(Index);

目录结构

Next.js 会将 pages 目录自动生成路由, 所以开发SPA , 自己的代码需要全部写到 components 或其他目录中.

|next-js-spa-demo

|components

| |Home

| | |index.tsx

| |Layout

| | |index.tsx

| |Log

| | |-index.tsx

| |Login

| | |index.tsx

| |MyRouter.tsx

|pages

| |404.tsx

| |index.tsx

| |_app.tsx

|pnpm-lock.yaml

|next.config.js

|package.json

|tsconfig.json

源码与预览

https://github.com/xxxxue/next-js-spa-demo

推荐文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。