#reactjs #react-router #next.js #router
#reactjs #react-маршрутизатор #next.js #маршрутизатор
Вопрос:
У меня есть компонент заголовка, который обновляет параметры url для выполнения вызова api и использует next router для передачи этих параметров на страницу результатов.
Я хочу иметь возможность снова выполнить поиск с этой страницы с помощью маршрутизатора, но страница не обновляется из-за того, что страница результатов остается той же.
Как я могу этого добиться?
Большое спасибо за любую помощь, код ниже.
Header.js
import { useState, useEffect, useContext } from "react";
import { useRouter } from "next/router";
export default function Header() {
const [searchText, setSearchText] = useState("");
const [impact, setImpact] = useState("");
const [worldwide, setWorldwide] = useState(false);
const router = useRouter();
const onClick = (e) => {
setWorldwide(e.target.checked);
};
const handleSubmit = (event) => {
event.preventDefault();
setImpact(impact);
let remote = "";
if (worldwide === true) {
remote = "Remote";
} else {
remote = "";
}
router.push({
pathname: `/remote-jobs`,
query: {
term: `${searchText}`,
impact: `${impact}`,
location: `${remote}`,
},
});
};
return (
<div>
<div className="p-4 flex flex-col items-center justify-center w-1/3 md:w-full">
<form onSubmit={handleSubmit}>
<select
onChange={(e) => setImpact(e.target.value)}
className="pl-2 pr-2 mr-4 h-10 rounded bg-white text-black md:h-12 md:pl-4 md:pr-4"
>
<option value="">choose an option</option>
<option value="sdg1">option1</option>
<option value="sdg2">option2</option>
</select>
<input
placeholder={"search"}
className="pl-2 pr-2 h-10 my-2 rounded bg-white text-black md:h-12 md:pl-4 md:pr-4"
onChange={(event) => {
setSearchText(event.target.value);
}}
/>
<button className="ml-4 pl-2 pr-2 rounded bg-black text-white md:h-12 md:pl-4 md:pr-4">
Go
</button>
<input
className="ml-4"
type="checkbox"
onClick={onClick}
value={!worldwide}
/>{" "}
</form>
</div>
</div>
</div>
);
}
Страница результатов:
import React, { useState, useEffect } from "react";
import Job from "../components/Job";
import Header from "../components/Header";
export default function App(key) {
const [jobs, setJobs] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const urlParams = new URLSearchParams(window.location.search);
const searchTerm = urlParams.get("term");
const searchImpact = urlParams.get("impact");
const searchLocation = urlParams.get("location");
const fetchJobs = async () => {
const url = `https://api.app/api/search?term=${searchTerm}amp;impact=${searchImpact}amp;location=${searchLocation}`;
const response = await fetch(url);
const info = await response.json();
setLoading(false);
setJobs(info);
};
fetchJobs();
}, []);
return (
<div className="App">
<Header />
{loading ? (
<div>...loading</div>
) : (
<div>
{jobs.length} jobs
<div>
{jobs.map((job) => (
<Job job={job} key={job.id} />
))}
</div>
</div>
)}
</div>
);
}
Ответ №1:
Вы должны использовать next router для получения значений запроса, а затем вы можете использовать эффект для извлечения новых данных при каждом изменении запроса
export default function App(key) {
const [jobs, setJobs] = useState([]);
const [loading, setLoading] = useState(true);
const { query: { term, impact, location } } = useRouter();
useEffect(() => {
const fetchJobs = async () => {
const url = `https://api.app/api/search?term=${term}amp;impact=${impact}amp;location=${location}`;
const response = await fetch(url);
const info = await response.json();
setLoading(false);
setJobs(info);
};
fetchJobs();
}, [term, impact, location]);
return (
<div className="App">
<Header />
{loading ? (
<div>...loading</div>
) : (
<div>
{jobs.length} jobs
<div>
{jobs.map((job) => (
<Job job={job} key={job.id} />
))}
</div>
</div>
)}
</div>
);
}