问题描述
我是 ReactJS 的新手。但习惯于使用 VueJS。以前,我在 VueJS 中开发项目。但是在 ReactJS 中,我在设置我想要的分页时遇到了困难。
每当用户更改搜索值时,应将页码重置为 1 并进行 API 调用以获取结果。
这给我添麻烦了。有人可以帮忙吗?
问题是如果我多次更改搜索值而不更改页面,则不会再次调用 API,因为页面值未更改。这是我的代码。
import React,{useCallback,useEffect,useState,useMemo,useRef} from 'react';
import {useHistory,useLocation} from "react-router-dom";
import _ from 'lodash';
const queryString = require('query-string');
import {Page,Card,DataTable,Filters,Link,Stack,Pagination,Spinner} from '@shopify/polaris';
function usePrevIoUs(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
export default function App() {
const params = queryString.parse(location.search);
const [from,setFrom] = useState(0);
const [to,setTo] = useState(0);
const [total,setTotal] = useState(0);
const [hasPrevIoUs,setHasPrevIoUs] = useState(false);
const [hasNext,setHasNext] = useState(false);
const [page,setPage] = useState(params.page ? parseInt(params.page) : 1);
const [queryValue,setQueryValue] = useState(params.search ? params.search : null);
const [items,setItems] = useState([]);
const [loading,setLoading] = useState(true);
const queryParams = useMemo(() => {
let queryParamsObject = {};
if (page > 1) queryParamsObject.page = page;
if (queryValue) queryParamsObject.search = queryValue;
return queryParamsObject;
},[page,queryValue]);
const prevPage = usePrevIoUs(page);
const prevQueryValue = usePrevIoUs(queryValue);
const handleFiltersQueryChange = useCallback((value) => setQueryValue(value),[]);
const handleQueryValueRemove = useCallback((value) => setQueryValue(null),[]);
const handleFiltersClearall = useCallback(() => handleQueryValueRemove(),[handleQueryValueRemove]);
const rows = useMemo(() => {
return items.map(item => {
return [
<Link removeUnderline url={`/items/${item.id}`}>{item.title}</Link>,item.email
];
});
},[items]);
const fetchItems = useCallback((params) => {
setLoading(true);
window.axios.get(`/items`,{params}).then((response) => {
setItems(response.data.data);
setFrom(response.data.from);
setTo(response.data.to);
setTotal(response.data.total);
setHasPrevIoUs(Boolean(response.data.prev_page_url));
setHasNext(Boolean(response.data.next_page_url));
setLoading(false);
});
},[]);
const debouncedSearch = useCallback(_.debounce((params) => {
if (params.page === page) {
history.push({pathname: '/items',search: queryString.stringify(params)});
fetchItems(params);
} else {
setPage(1);
}
},1000),[]);
useEffect(() => {
if (typeof prevQueryValue !== "undefined" && prevQueryValue !== queryValue) {
debouncedSearch(queryParams);
} else {
history.push({pathname: '/items',search: queryString.stringify(queryParams)});
fetchItems(queryParams);
}
},queryValue]);
return (
<Filters
queryValue={queryValue}
filters={[]}
onQueryChange={handleFiltersQueryChange}
onQueryClear={handleQueryValueRemove}
onClearall={handleFiltersClearall}
queryPlaceholder="Filter items"
/>
<DataTable
columnContentTypes={[
'text','text',]}
headings={[
'Col1','Col2',]}
rows={rows}
footerContent={`Showing ${from} to ${to} of ${total} results`}
/>
{hasPrevIoUs || hasNext ? <div className="pagination"><Stack distribution="center"><Pagination hasPrevIoUs={hasPrevIoUs} hasNext={hasNext} onPrevIoUs={() => setPage(parseInt(page) - 1)} onNext={() => setPage(parseInt(page) + 1)} /></Stack></div> : null}
);
}
解决方法
我错了。只需在 debouncedSearch 函数中的 if 条件中再添加一个条件即可。
这是新功能
const debouncedSearch = useCallback(_.debounce((params) => {
if ((params.page && params.page === page) || (!params.page && page === 1)) {
history.push({pathname: '/items',search: queryString.stringify(params)});
fetchItems(params);
} else {
setPage(1);
}
},1000),[]);
但是,我仍然认为这不是正确的标准方式。因此,如果有人知道正确的方法,将不胜感激。