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

NextJS中router.push未跳转指定路径,页面跳转异常求助

NextJS页面跳转传参问题:点击按钮未跳转反而重载当前页面

我是NextJS新手,尝试从booking/details/[id]页面向booking/checkout页面传递数据时遇到问题。点击绑定passData()方法的Proceed按钮后,router.push没跳转到指定的pathname="/booking/checkout/",反而重载了当前页面,数据直接附加到当前页面的URL里。希望点击按钮后能正确跳转到checkout页面,同时把GatherAllData()里的数据传过去。


相关代码与页面结构

details/[id]/index.tsx

import Card from 'react-bootstrap/Card';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';
import Button from 'react-bootstrap/Button';
import Hotel from '../../../../src/api/booking/booking';
import { useEffect, useState } from 'react';
import Container from 'react-bootstrap/Container';
import ListGroup from 'react-bootstrap/ListGroup';
import Form from 'react-bootstrap/Form';
import Layout from '@/src/components/layout';
import { useRouter } from 'next/router';
import 'bootstrap/dist/css/bootstrap.min.css'
import Carousel from 'react-bootstrap/Carousel';
import ProgressBar from 'react-bootstrap/ProgressBar';
import Modal from 'react-bootstrap/Modal';
import React, {useRef} from 'react';
import ButtonGroup from 'react-bootstrap/ButtonGroup';
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';
import Link from 'next/link'

export default function HotelDetails(){

    const router = useRouter();

    const {id} = router.query;

    ...

    const GatherAllData = () => {
        return (
            {
                "fullname": formvalues['fullname'],
                "email": formvalues['email'],
                "phone": formvalues['phone'],
                "accountnumber": formvalues['accountnumber'],
                "check_in": values.check_in,
                "check_out": values.check_out,
                "voucher_applied": values3,
                "total_discount": currencyFormatter.format(totalDiscount),
                "payment_method": selectedpayment,
                "add_on_id": addOnAdded()[1],
                "add_on_name": addOnAdded()[0],
                "grand_total": priceList(id)
            }
        )
    }

    const passData = () => {
        router.push({
            pathname: "/booking/checkout/",
            query: GatherAllData()
        })
    }

    return(
        <Layout>   
                
                ...

                  <Button variant='success' type='submit' onClick={()=>passData()}>Proceed</Button>
                                        
                ...
)}

checkout/index.tsx

import Card from 'react-bootstrap/Card';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';
import Button from 'react-bootstrap/Button';
import Hotel from '../../../src/api/booking/booking';
import { useEffect, useState } from 'react';
import Container from 'react-bootstrap/Container';
import ListGroup from 'react-bootstrap/ListGroup';
import Form from 'react-bootstrap/Form';
import Layout from '@/src/components/layout';
import { useRouter } from 'next/router';
import 'bootstrap/dist/css/bootstrap.min.css'
import Carousel from 'react-bootstrap/Carousel';
import ProgressBar from 'react-bootstrap/ProgressBar';
import Modal from 'react-bootstrap/Modal';
import React, {useRef} from 'react';
import ButtonGroup from 'react-bootstrap/ButtonGroup';
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';

export default function HotelCheckout(){
   
    const router = useRouter();

    console.log(router.query)

    return(
        <Layout>
            <Container>
                <Row>
                    <h1>Hello, World!</h1>
                </Row>
            </Container>
        </Layout>
    )

}

根目录index.tsx

import Head from 'next/head'
import Image from 'next/image'
import { Inter } from 'next/font/google'
import styles from '@/styles/Home.module.css'
import Layout from '@/src/components/layout'
import 'bootstrap/dist/css/bootstrap.min.css'
import HotelList from './booking'
import HotelDetails from './booking/details/[id]'
import HotelCheckout from './booking/checkout'

const inter = Inter({ subsets: ['latin'] })

export default function Home() {
  return (
    <div>
      <Layout>
        <HotelList/>
      </Layout>
    </div>
  )
}

页面文件夹结构

页面文件夹结构


问题原因与解决办法

核心问题

你的按钮是type='submit',而且它肯定包裹在<form>标签里。点击submit按钮会触发表单的默认提交行为,直接重载页面,把router.push的跳转逻辑给覆盖了。

解决办法(二选一即可)

  1. 阻止表单默认行为
    修改passData函数,加上阻止默认行为的代码:

    const passData = (e) => {
        e.preventDefault(); // 阻止表单自动提交
        router.push({
            pathname: "/booking/checkout", // 可以去掉末尾斜杠,避免路由匹配问题
            query: GatherAllData()
        })
    }
    

    然后修改按钮的点击事件,把事件对象传进去:

    <Button variant='success' type='submit' onClick={(e)=>passData(e)}>Proceed</Button>
    
  2. 修改按钮类型
    如果这个按钮不需要提交表单,直接把type改成button:

    <Button variant='success' type='button' onClick={()=>passData()}>Proceed</Button>
    

验证

改完之后点击按钮,应该能正常跳转到checkout页面,打开控制台就能看到router.query里已经拿到传递的数据了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:07:11