3

I have a Header component which updates url parameters to make an api call, and uses next router to pass these parameters to the results page.

I want to be able to search again from this page using router, but the page does not refresh due to the results page being the same.

How can I acheive this?

Many thanks for any help, code below.

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

Results page:

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}&impact=${searchImpact}&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 Answer 1

4

You should use next router to get the query values and then you can useEffect to fetch new data whenever the query changes

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}&impact=${impact}&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>
  );
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.