I made a search panel component, searchPanel.tsx. On it, a button grabs the details from the form (Flight From, Flight To, Flight Date, and some other data), then sends that to a new page.
Here's the searchPanel.tsx:
'use client';
import "./searchPanel.css";
import React, { useState } from "react";
import { useRouter } from "next/navigation";
export default function SearchPanel() {
const router = useRouter();
const [isUsingFlightNum, setIsUsingFlightNum] = useState(false);
const [locFromValue, setLocFromValue] = useState('');
const [locToValue, setLocToValue] = useState('');
const [flightNumValue, setFlightNumValue] = useState('');
const [flightDateValue, setFlightDateValue] = useState('');
const locFromChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setLocFromValue(e.target.value);
};
const locToChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setLocToValue(e.target.value);
};
const flightNumChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFlightNumValue(e.target.value);
};
const flightDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFlightDateValue(e.target.value);
};
const handleSubmit = async (formData: FormData) => {
const flightFrom = formData.get('flightFrom')?.toString() || "";
const flightTo = formData.get('flightTo')?.toString() || "";
const flightNumber = formData.get('flightNumber')?.toString() || "";
const flightDate = formData.get('flightDate')?.toString() || "";
if (flightDate !== "" && (flightFrom !== "" && flightTo !== "" || flightNumber !== "")) {
const params = new URLSearchParams();
params.set('is_using_flight_number', isUsingFlightNum.toString());
params.set('flight_from', flightFrom);
params.set('flight_to', flightTo);
params.set('flight_num', flightNumber);
params.set('flight_date', flightDate);
router.push(`/flight/choose?${params.toString()}`)
} else {
alert("One or more required fields are missing.");
}
}
return (
<div>
Front end code here
</div>
);
}
That routes to another page, flight/choose/page.tsx. This page now takes the parameters from the search panel, and uses those as parameters for an API call:
export default async function SelectFlight( {searchParams} : MyPageProps ) {
// const [selectedFlightCardId, setSelectedFlightCardId] = useState(-1);
// ^^ Code that I need
const params = await searchParams;
const isUsingFlightNum = params!.is_using_flight_number || "";
const flightFrom = params!.flight_from || "";
const flightTo = params!.flight_to || "";
const flightNumber = params!.flight_num || "";
const flightDate = params!.flight_date || "";
const url = new URL(`${BASE_API_URL}/api/flights`);
const options = {
method: "GET",
};
url.searchParams.append('is_using_flight_number', isUsingFlightNum.toString());
url.searchParams.append('flight_from', flightFrom);
url.searchParams.append('flight_to', flightTo);
url.searchParams.append('flight_num', flightNumber);
url.searchParams.append('flight_date', flightDate);
const response = await fetch(url, options);
const result = await response.json();
const flightData = result.data;
const handleClick = (event) => {
const clickedId = event.target.id;
console.log(`clickedId`, clickedId);
}
return (
<div>
Front end code here
</div>
);
}
This works, until I add "use client" at the very top, which I need for a useState to update a clicked <div> styling and store the ID.
Then the page just repeatedly calls the fetch code, until I kill the project or navigate elsewhere.
I have no idea what to do. Removing my code and simply adding something like a console.log("help") would see help printed repeatedly in the console as well.
useEffectwith the params as dependencylet flightData: any[] = []at the very top of the code.flightData. If so, you need to maintain a state(useState) forflightDataand set the data once its received. To render a client component it needs to be in the life-cycle hook. So maintain a state for that data from which the component gets built