You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS如何复用动态路由,无需req.query实现管理员编辑用户资料?

解决方法

首先,你的路由文件夹结构pages/edit/[userId]/index.jsx已经符合Next.js动态路由的要求,核心是直接通过路由路径传递userId,同时区分普通用户和管理员的访问逻辑:

1. 调整访问路径

  • 普通用户编辑自身资料:访问/user/edit,我们把这个路径作为入口,自动重定向到/edit/[当前用户ID]
  • 管理员编辑指定用户:直接访问/edit/[目标用户ID](比如/edit/123)

2. 实现普通用户的重定向页面

新建pages/user/edit.jsx,作为普通用户的编辑入口,自动跳转到自己的动态路由页面:

import { useEffect } from 'react';
import { useRouter } from 'next/router';

export default function UserEditRedirect() {
  const router = useRouter();
  // 这里替换成你获取当前登录用户ID的逻辑(比如从Auth状态、Session中读取)
  const currentUserId = '当前登录用户的ID';

  useEffect(() => {
    if (currentUserId) {
      router.push(`/edit/${currentUserId}`);
    }
  }, [currentUserId, router]);

  return <div>跳转中...</div>;
}

3. 在动态路由页面获取userId并处理权限

在pages/edit/[userId]/index.jsx中,直接从动态路由参数获取userId,无需依赖URL query:

客户端获取(适用于客户端渲染场景)

import { useRouter } from 'next/router';
import { useState, useEffect } from 'react';

export default function EditUserPage() {
  const router = useRouter();
  const { userId } = router.query; // 这里的userId是动态路由参数,不是URL query参数
  const [userData, setUserData] = useState(null);
  // 替换成你获取当前登录用户信息的逻辑
  const currentUser = { id: '当前用户ID', isAdmin: false };

  useEffect(() => {
    if (!userId) return;

    // 权限校验:普通用户只能编辑自己的资料
    if (!currentUser.isAdmin && userId !== currentUser.id) {
      router.push(`/edit/${currentUser.id}`);
      return;
    }

    // 根据userId获取目标用户的资料
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => setUserData(data));
  }, [userId, currentUser, router]);

  if (!userData) return <div>加载中...</div>;

  return (
    <div>
      <h2>编辑用户:{userData.name}</h2>
      {/* 你的编辑表单 */}
      <input type="text" defaultValue={userData.name} />
      {/* 其他表单字段 */}
    </div>
  );
}

服务端获取(适用于服务端渲染场景,更安全)

import { useRouter } from 'next/router';

// 服务端获取数据并做权限校验
export async function getServerSideProps(context) {
  // Next.js 13+ Pages Router用context.params获取路由参数,旧版本用context.query.userId
  const { userId } = context.params;
  // 从请求中获取当前登录用户信息(比如从Session、Cookie中读取)
  const currentUser = await getCurrentUserFromSession(context.req);

  // 未登录用户跳转登录页
  if (!currentUser) {
    return {
      redirect: { destination: '/login', permanent: false }
    };
  }

  // 普通用户只能编辑自己的资料
  if (!currentUser.isAdmin && userId !== currentUser.id) {
    return {
      redirect: { destination: `/edit/${currentUser.id}`, permanent: false }
    };
  }

  // 获取目标用户的资料
  const userData = await fetchUserById(userId);

  return { props: { userData, currentUser } };
}

export default function EditUserPage({ userData, currentUser }) {
  return (
    <div>
      <h2>编辑用户:{userData.name}</h2>
      {/* 你的编辑表单 */}
      <input type="text" defaultValue={userData.name} />
      {/* 其他表单字段 */}
    </div>
  );
}

// 以下是示例工具函数,替换成你项目中的实际实现
async function getCurrentUserFromSession(req) {
  // 从req中获取当前登录用户逻辑
  return { id: '当前用户ID', isAdmin: false };
}

async function fetchUserById(userId) {
  // 根据ID获取用户数据逻辑
  return { id: userId, name: '目标用户名称' };
}

关键注意点

  • 权限校验必须做:不管是客户端还是服务端,都要校验当前用户是否有权限编辑目标用户,防止普通用户手动输入其他用户ID越权操作
  • 动态路由参数的获取:客户端用router.query.userId,服务端在Next.js 13+ Pages Router中用context.params.userId,旧版本用context.query.userId(这里的query是路由参数,不是URL上的?xxx参数)

内容的提问来源于stack exchange,提问作者Kal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:25:24