Home > OS >  How to reset a component's state on doing router.push for same component
How to reset a component's state on doing router.push for same component

Time:12-31

I am trying to reset state on router.push I have a header component having search option, When a user Search Something router.push sends him to '/search/${search}' So basically on search Page(SSR)

on Search Component i Put limit and skip as well for loadMore Functionality, when i try to search something from home page or any other page so it runs smoothly because search page renders and skip, limit gets reset

Problem - My main problem is that When i try to search something from Search Page then the skip and limit old state values keeps same doesn't change router.push But when i reload page the state gets reset. Why is that?

my router.push on header component -

const Header = ({searched }) => {
  const [values, setValues] = useState({
    search: "",
  });
  const { search } = values;
  const router = useRouter();
  useEffect(() => {
    setHydrated(true);
    // getPage();
    // setValues({ ...values, search: searched });
    console.log(searched);
  }, []);
  if (!hydrated) {
    return null;
  }

return (
        <React.Fragment>
          <h1 className="d-flex align-items-center mb-3 justify-content-between">
            <span className="">Feature Request</span>
            <div className="d-flex align-items-center">
              <Input
                className="search"
                placeholder="Search Something..."
                value={search}
                onChange={(e) => {
                  setValues({ ...values, search: e.target.value });
                }}
              />
              <AiOutlineSearch
                onClick={() => {
                  router.push(`/search/${search}`);
                }}
                size={25}
              />
            </div>
          </h1>

          <p>Your Suggestion Matters</p>
        </React.Fragment>
      );
    }

My Search page -

import React from "react";
import { Button, Card, CardText, CardTitle, Col, Container } from "reactstrap";
import Layout from "../../components/Layout";
import Link from "next/link";
import { useState, useEffect } from "react";
import { searchData } from "../../api/page";
import { getCookie } from "../../api/auth";
import { useRouter } from "next/router";
import InfiniteScroll from "react-infinite-scroll-component";
const SearchPage = ({ data }) => {
  const [values, setValues] = useState({
    pages: [],
    skip: 0,
    limit: 5,
    hasMore: true,
  });
  const { pages, skip, limit, hasMore } = values;
  const router = useRouter();
  const token = getCookie("token");
  const getSearchedData = async () => {
    console.log(hasMore);
    await setValues({ ...values, skip: 0, limit: 5 });

    const search = router.query.search;
    await searchData(search, skip, limit).then((data) => {
      if (data.error) {
        console.log(data.error);
      } else {
        setValues({ ...values, pages: data, skip: 0 });
      }
    });
  };
  useEffect(() => {
    getSearchedData();
    console.log("UseEffect chal gya");
  }, [data]);

  const mapSearchData = () => {
    return pages.map((p, i) => {
      return (
        <div key={i} className="mt-4">
          <Card body className="manual-card">
            <CardTitle tag="h5">{p.title}</CardTitle>
            <CardText>{p.excerpt}</CardText>
            <Button color="primary" className="w-25" size="sm">
              <Link href={`/pages/${p.slug}`}>Go To Page</Link>
            </Button>
          </Card>
        </div>
      );
    });
  };
  const fetchMoreData = () => {
    console.log("Best");
    const search = router.query.search;
    let toSkip = skip   limit;
    searchData(search, toSkip, limit).then((data) => {
      if (data.error) {
        console.log(data.error);
      } else {
        const tempArray = [...pages, ...data];
        setValues({
          ...values,
          pages: tempArray,
          skip: toSkip,
          hasMore: !(data.length < limit),
        });
      }
    });
  };

  return (
    <Layout search={router.query.search}>
      <Container className="mt-5">
        <Col>
          {pages && pages.length ? (
            mapSearchData()
          ) : (
            <div className="">No Such Pages Present!</div>
          )}
          {hasMore && (
            <Button
              className="d-flex mx-auto my-4"
              color="primary"
              onClick={fetchMoreData}
            >
              Load More
            </Button>
          )}
        </Col>
        ;
      </Container>
    </Layout>
  );
};

export default SearchPage;

export async function getServerSideProps(context) {
  const { search } = context.query;
  // console.log(slug);
  if (!search) {
    return {
      props: { data: null },
    };
  }
  let result = null;
  try {
    const res = await fetch(
      `${process.env.NEXT_PUBLIC_API}/pages/search/${search}`
    );
    result = await res.json();
  } catch (error) {
    return {
      props: { data: null },
    };
  }
  return {
    props: { data: result },
  };
}

When i am on any other page instead of search page then router.push works fine it resets the skip and limit and fetch all data on starting

But when i am on search page itself and i search something from there then skip and limit states doesnt change, data get fetched on basis of skip and limit And on page reload I Get complete data with skip and limit resetted.

CodePudding user response:

Just reset the value before calling router.push() inside onClick callback of <AiOutlineSearch>

CodePudding user response:

Make these changes in Search Page:

useEffect(() => {
    resetState() // create a function to reset the state 
    getSearchedData();
    console.log("UseEffect chal gya");
  }, [data, router.query]); // so whenever your search query changes, the state would be reset and new data will be fetched.
  • Related