javascript 如何重置一个组件的状态上做路由器,推动相同的组件

rkttyhzu  于 2023-01-01  发布在  Java
关注(0)|答案(3)|浏览(113)

我正在尝试重置路由器上的状态。push我有一个具有搜索选项的标头组件,当用户搜索某个路由器时。push将其发送到“/search/${search}”因此基本上在搜索页面(SSR)上
在搜索组件上,我为loadMore功能设置了限制和跳过,当我尝试从主页或任何其他页面搜索内容时,由于搜索页面呈现和跳过,限制被重置

问题-我的主要问题是,当我试图从搜索页面搜索东西,然后跳过和限制旧状态值保持不变不改变路由器。推但当我重新加载页面的状态得到重置。为什么?

  • 我的路由器。按下标头组件 * -
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>
      );
    }

我的搜索页面-

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

当我在任何其他页面,而不是搜索页面,然后router.push工作正常,它重置跳过和限制,并获取所有数据开始
但是,当我在搜索页面本身,我从那里搜索的东西,然后跳过和限制状态不会改变,数据被提取的基础上跳过和限制,并在页面重新加载我得到完整的数据与跳过和限制重置。

v8wbuo2f

v8wbuo2f1#

只需在<AiOutlineSearch>onClick回调内调用router.push()之前重置该值

46scxncf

46scxncf2#

在搜索页面中进行以下更改:

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.
drkbr07n

drkbr07n3#

根据文档:
当导航到Next.js中的同一页面时,默认情况下不会重置页面的状态,因为react不会卸载,除非父组件已更改。
如果您不希望出现此行为,可以选择以下几种方法:
1.使用效果

// Fetch new data each time the query search is updated
useEffect(() => {
  getSearchedData();
}, [router.query.search])

1.使用React密钥
它涉及到使用router.asPath,但此方法已在NextJS 13中删除。您可以使用不同的方法完成相同的操作(用于遗留目的)。
NextJS 12 router methods
NextJS 13 router methods

相关问题