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的跳转逻辑给覆盖了。
解决办法(二选一即可)
阻止表单默认行为
修改passData函数,加上阻止默认行为的代码:const passData = (e) => { e.preventDefault(); // 阻止表单自动提交 router.push({ pathname: "/booking/checkout", // 可以去掉末尾斜杠,避免路由匹配问题 query: GatherAllData() }) }然后修改按钮的点击事件,把事件对象传进去:
<Button variant='success' type='submit' onClick={(e)=>passData(e)}>Proceed</Button>修改按钮类型
如果这个按钮不需要提交表单,直接把type改成button:<Button variant='success' type='button' onClick={()=>passData()}>Proceed</Button>
验证
改完之后点击按钮,应该能正常跳转到checkout页面,打开控制台就能看到router.query里已经拿到传递的数据了。
内容的提问来源于stack exchange,提问作者kucingcat
相关产品推荐
相关产品推荐

