обновление маршрутизатора nextjs при изменении параметра URL

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