如果使用 useEffect 更改了另一个过滤器,则重置为第一页

reset to first page if another filter is changed with useEffect

我正在使用 React 功能组件。

要从 api 调用数据,可以使用过滤器和分页。当我更改过滤器类型时,分页必须 return 到第一页。

const pageChange = (page) => {
        setPage(page);
    };

 useEffect(() => {
        async function fetchData() {
            const dateFilter = start && end ? `start=${start}&end=${end}` : null;
            const pageFilter = `offset=${
        (page - 1) * ITEMS_PER_PAGE
      }&limit=${ITEMS_PER_PAGE}`;
            const defaultFilters = `${dateFilter?dateFilter:''}${dateFilter?'&':''}${pageFilter}`;
            let request = null;
            switch (type) {
                case "upcoming":
                    request = fetchUpcomingLaunches(defaultFilters);
                    break;
                case "successful":
                    request = fetchLaunches(`${defaultFilters}&launch_success=true`);
                    break;
                case "failed":
                    request = fetchLaunches(`${defaultFilters}&launch_success=false`);
                    break;
                default:
                    request = fetchLaunches(defaultFilters);
                    break;
            }
            try {
                setIsLoading(true);
                const response = await request;
                setItems(getItems(response.data));
                setIsLoading(false);
            } catch (err) {
                setIsLoading(false);
            }
        }
        fetchData();
    }, [start, end, type, page]);

我正在使用 material ui 分页:

   <Pagination
          count={20}
          variant="outlined"
          shape="rounded"
          size="large"
          page={page}
          onChange={(event, val) => pageChange(val)}
        />

这里的开始、结束和类型是过滤器。如果任何过滤器发生变化,则必须调用 api 并刷新数据。 api 必须 return 基于页面的分页响应。我的问题是,当更改任何其他过滤器时,页面应重置为第一页,并且应从第一页加载数据。是否可以使用两个 useEffect 挂钩?我已经尝试过 useEffect with type, start, end dependecies 。截至目前,api 在再次调用 setPage 时被调用了两次。

filter改变后,可以setPage到第1页,在useEffect中添加setPage with condition filter。例如

useEffect(() => {
   setPage(1);
},[start, end])

您需要添加一个具有过滤器依赖性的新 useEffect,并利用 useRef 来防止 api 在过滤器更改时被调用两次。

灵感来源于此

const isFilterApplied = useRef(false);

useEffect(() => {
    console.log("Filter change effect")
    isFilterApplied.current = true;
    setCurrentPage(1);
  }, [start, end, type]);
  
  useEffect(() => {
    async function fetchData() {
      const dateFilter = start && end ? `start=${start}&end=${end}` : null;
      const pageFilter = `offset=${(page - 1) * ITEMS_PER_PAGE}&limit=${ITEMS_PER_PAGE}`;
      const defaultFilters = `${dateFilter ? dateFilter : ""}${dateFilter ? "&" : ""}${pageFilter}`;
      let request = null;
      switch (type) {
        case "upcoming":
          request = fetchUpcomingLaunches(defaultFilters);
          break;
        case "successful":
          request = fetchLaunches(`${defaultFilters}&launch_success=true`);
          break;
        case "failed":
          request = fetchLaunches(`${defaultFilters}&launch_success=false`);
          break;
        default:
          request = fetchLaunches(defaultFilters);
          break;
      }
      try {
        setIsLoading(true);
        const response = await request;
        setItems(getItems(response.data));
        setIsLoading(false);
      } catch (err) {
        setIsLoading(false);
      }
    }

    if (isFilterApplied.current && currentPage !== 1) {
      return;
    }

    console.log("Main effect")

    fetchData();
  }, [start, end, type, page]);

  useEffect(() => {
    setPage(1);
  }, [start, end, type]);

  const changePage = (page) => {
    isFilterApplied.current = false;
    setCurrentPage(page);
  };

一个示例 codesandbox 如果有帮助的话,使用不同的代码库。