Nextjs状态未在路由更改时更新

b4qexyjb  于 2023-04-05  发布在  其他
关注(0)|答案(2)|浏览(153)

我知道在同一个主题中有很多问题。我已经阅读了大约2天关于这个问题,我不能让它工作。所以我的情况是这样的:
我在我的Nextjs应用程序中有几个动态路由,每个路由的内容中都有一个表。我根据我设置的一些过滤器来更新该表的状态,这些过滤器工作正常,但是当路由发生变化时,表的状态仍然保持以前的状态。我尝试向Table组件添加一个键,如下所示:key={router.asPath}但它没有任何区别。
我还向getStaticProps添加了一个密钥,如下所示:

return {
    props: {
      pageData,
      serverLocations,
      faq,
      key: data?.serverLocations?.data[0]?.attributes.Slug,
    },
    revalidate: 1,
  };

现在我尝试更新router.events上的状态,但同样,没有乐趣!
下面是我的代码,你可以看看我做错了什么:

import { useCallback, useEffect, useState } from "react";
import { Button, useTheme } from "@mui/material";
import PricingTable from "./PricingTable";
import FiltersDialog from "./PricingFilters";
import IconFilters from "./icons/IconFilters";
import Spacer from "./dynamicBlocks/Spacer";
import { useRouter } from "next/router";

export default function TableWithFilters({ theData }: any) {
  const theme = useTheme();
  const router = useRouter();
  const [filtersDialogOpen, setFiltersDialogOpen] = useState(false);

  const Columns = Object.entries(theData[0]).map(([property, columnLabel]) => ({
    property,
    columnLabel,
  }));

  const [state, setState] = useState({
    data: theData,
    filters: Columns.slice(3, -2),
    columns: Columns,
    filterObj: Columns.slice(3, -2).reduce(
      (r: any, { property }: any) => ((r[property] = 0), r),
      {}
    ),
  });
  

  const onFilterApply = ({ target: { value, name } }: any) => {
    const newFilterObj = { ...state.filterObj, [name]: value };
    setState({
      ...state,
      filterObj: newFilterObj,
      data: theData.filter((props: any) =>
        Object.entries(newFilterObj).every(([key, val]: any) => {
          return props[key] >= val;
        })
      ),
    });
  };

  const onRouteChange = useCallback(() => {                              |
    setState({                                                           |
      ...state,                                                          |
      data: theData,                                                     |
      filterObj: Columns.slice(3, -2).reduce(                            |
        (r: any, { property }: any) => ((r[property] = 0), r),           |
        {}                                                               |
      ),                                                                 |
    });                                                                  | This is
  }, [setState]);                                                        | the code
                                                                         |I am trying
  useEffect(() => {                                                      |to use to 
    // subscribe                                                         |fix this
    router.events.on("routeChangeComplete", onRouteChange);              |
    // unsubscribe                                                       |
    return () => router.events.off("routeChangeComplete", onRouteChange);|
  }, [onRouteChange, router.asPath]);                                    |
                                                                         |
  console.log("STATEEE", state);
  console.log("DATAAA", theData);

  return (
    <>
      <FiltersDialog
        openFilters={filtersDialogOpen}
        closeFilters={() => setFiltersDialogOpen(false)}
        staticData={theData}
        filterData={state.filterObj}
        filterProperties={state.filters}
        onFilter={onFilterApply}
      />
      <Button
        onClick={() => setFiltersDialogOpen(!filtersDialogOpen)}
        startIcon={
          <IconFilters
            width='24'
            height='24'
            color={theme.palette.primary.main}
          />
        }
      >
        Open Filters
      </Button>
      <Spacer spacerHeight='40px' />
      <PricingTable
        key={router.asPath}
        tableData={state.data}
        tableColumns={state.columns}
        tableHeader={Columns}
      />
    </>
  );
}
cnjp1d6j

cnjp1d6j1#

你可以参考这个。我猜你的组件位置不会改变,并且保持它的状态,实际上我可以模拟你的情况。所以你可以尝试按照这些选项吗?我认为选项2更容易实现。你可以检查一下,只是把“关键”的 prop 与Math.random()是否工作正常。如果它是确定的,请替换Math.random()与您的适当值。(正如我提到的,使用Math.random()只是为了检查这个解决方案是否正确。)

parent-component.jsx

export default ParentComponent(){
    return <TableWithFilters key={Math.random()} theData={...}>...</TableWithFilters>
}
ruyhziif

ruyhziif2#

任何人都有类似的问题。我的错误是我不应该在onRouteChange函数中使用useCallback,而应该是这样的普通函数:

const onRouteChange = () => {
    setState({
      ...state,
      data: theData,
    });
  };

然而@iamippei的解决方案也可以工作,但是我把key放在了错误的位置。所以你可以选择任何一种解决方案。两种都可以工作。

相关问题