如果使用 useEffect 更改了另一个过滤器,则重置为第一页
Posted
技术标签:
【中文标题】如果使用 useEffect 更改了另一个过滤器,则重置为第一页【英文标题】:reset to first page if another filter is changed with useEffect 【发布时间】:2021-06-04 22:30:29 【问题描述】:我正在使用 react 功能组件。
要从 api 调用数据,有可用的过滤器和分页。当我更改过滤器类型时,分页必须返回到第一页。
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]);
我正在使用材质 ui 分页:
<Pagination
count=20
variant="outlined"
shape="rounded"
size="large"
page=page
onChange=(event, val) => pageChange(val)
/>
这里的开始、结束和类型是过滤器。如果任何过滤器发生变化,则必须调用 api 并刷新数据。 api 必须根据 page 返回分页响应。我的问题是,当任何其他过滤器发生更改时,页面应重置为第一页,并且应从第一页加载数据。是否可以使用两个 useEffect 挂钩?我试过 useEffect 和 type, start, end dependecies 。截至目前,该 api 被调用了两次,因为 setPage 再次被调用。
【问题讨论】:
当我刚开始反应时,我有一个类似的问题here。检查答案中的代码框。 @SuleymanSah 看过了,我不明白它会如何阻止 useEffct 被调用两次 看来你的问题和我的有点不一样。 @SuleymanSah true。实际上,如果我们可以从后端获取项目总数,这个问题将得到解决。分页组件将处理它 这可以解决你的问题:***.com/questions/57240169/… 【参考方案1】:您需要添加一个带有过滤器依赖项的新 useEffect,并利用useRef 防止过滤器更改时调用两次。
来自answer的想法
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,如果有帮助,可以使用不同的代码库。
【讨论】:
【参考方案2】:过滤器更改后,您可以将setPage设置为第1页,并在useEffect中添加setPage和条件过滤器。例如
useEffect(() =>
setPage(1);
,[start, end])
【讨论】:
这个我试过了,这种情况下api会在第一次Useeffect中调用两次,数据会根据哪个请求先返回响应而受到影响 @MohitHarshan 我认为第二个 useEffect 不会导致 API 被调用两次。肯定有其他原因,如果你能在codesandbox中提供你的应用的基本版本,那就很容易找到原因了。 是的,比如dependecy start发生变化,会调用api useeffct,因为它依赖于start,第一次useEffect调用setPage时,会再次调用第二次useEffect@SuleymanSah以上是关于如果使用 useEffect 更改了另一个过滤器,则重置为第一页的主要内容,如果未能解决你的问题,请参考以下文章
导航栏不会根据路由条件在 app.js 中呈现。路由更改时不会触发 Useeffect
使用 socket.io 将新的数组更改应用到 useEffect 并更改流
从 React 中的 useEffect 挂钩更改复选框选中状态?