router.push not redirect to defined path and it's load current page instead

i’m new in NextJS and i’m getting stuck in the situation that i need to pass data from current page to another page, but instead of load defined path in router.push which is pathname: "/booking/checkout/", but it’s load current page.

i need to pass the data inside GatherAllData() function to another page to process that data in the destination page. when i clicked the Proceed button that has onClick{()=>passData() to load a function that has router.push to http://localhost:3000/booking/checkout?data, it’s redirect to it’s own page (http://localhost:3000/booking/details/3?data)

here is my code:

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 under pages folder

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>
  )
}

my project pages folder structure

enter image description here

i want to when i click Proceed button it’s redirect to booking/checkout page and passing the data from booking/[id]/details/index.tsx to booking/checkout/index.tsx.

>Solution :

That "success" button is type="submit"…. so I suspect there is a form element involved somewhere here that is reloading the page, e.g. the import Form from 'react-bootstrap/Form';.

<Button
  variant='success'
  type='submit' // <-- submit button
  onClick{passData}
>
  Proceed
</Button>

There are a few options:

  • On the form element’s onSubmit handler you should call preventDefault on the onSubmit event object to prevent the default form action from taking place which results in the page reloading on the current URL path.

    If there’s a submit handler this is also where you’d want to place the navigation logic.

    const onSubmit = e => {
      e.preventDefault(); // <-- don't submit the form!
    
      ... the rest of the submit logic ...
    
      router.push({
        pathname: "/booking/checkout/",
        query: GatherAllData()
      });
    };
    
    <Form onSubmit={onSubmit}>
      ...
    
      <Button
        variant='success'
        type='submit'
      >
        Proceed
      </Button>
    
      ...
    </Form>
    
  • If there’s not any form element involved, or maybe there’s one rendered higher up in the ReactTree and you don’t actually want to submit a form with this button then specify the button to not be a submit button

    <Button
      variant='success'
      type='button' // <-- regular old button
      onClick{passData}
    >
      Proceed
    </Button>
    

Leave a Reply