import React, { FC, useEffect, useMemo, useRef, useState } from 'react';
import QuestionCard from '@/components/QuestionCard';
import { Typography, Spin, Empty } from 'antd';
import styles from './index.module.scss';
import ListSearch from '@/components/ListSearch';
import { useInViewport , useRequest, useDebounceFn} from 'ahooks';
import { getQuestionList } from '@/api/question'
import { useSearchParams } from 'react-router-dom'
import { LIST_SEARCH_KEYWORD_KEY } from '@/constants';
const { Title } = Typography;
const List: FC = () => {
const [started, setStarted] = useState(false); // 是否已经开始加载 (防抖,有延迟时间)
const [page, setPage] = useState(1);
const [list, setList] = useState([]);
const [total, setTotal] = useState(0);
const ref = useRef(null);
const [inViewport] = useInViewport(ref);
const [searchParams] = useSearchParams();
const haveMoreData = total > list.length; // 判断是否有更多数据
const { run: load, loading } = useRequest(async () => {
return await getQuestionList({
page,
pageSize: 10,
keyWord: searchParams.get(LIST_SEARCH_KEYWORD_KEY) || '',
})
}, {
manual: true,
onSuccess(result) {
// 加载完成后 拼接列表 page+1 设置total
const { list: data = [], total } = result;
setList(list.concat(data));
setTotal(total);
setPage(page + 1);
}
})
const { run: tryLoadMore } = useDebounceFn(() => {
if (inViewport) {
load();
setStarted(true)
}
}, {
wait: 500
})
// 页面初次加载
useEffect(() => {
tryLoadMore();
}, [searchParams])
// 监听滚动
useEffect(() => {
if (haveMoreData) {
tryLoadMore()
}
}, [inViewport, haveMoreData])
const LoadMoreContentEle = useMemo(() => {
if (!started || loading) return <Spin></Spin>
if (total === 0) return <Empty description="暂无数据"></Empty>
if (!haveMoreData) return '没有更多了...'
return '开始加载下一页'
}, [started, loading, haveMoreData])
return (
<div className={styles.wrap}>
<div className={styles.header}>
<Title level={3}>我的问卷</Title>
<ListSearch />
</div>
<div className={styles.content}>
{list.length > 0 &&
list.map((question: any) => {
const { _id } = question;
return <QuestionCard key={_id} {...question} />;
})}
<div ref={ref} className="flex-row-center">
{LoadMoreContentEle}
</div>
</div>
</div>
);
};
export default List;
这是完整代码。就是页面初次加载那里有点不能理解,已经监听了searchParams, 为什么当我手动去修改keyword时会触发执行,但是通过listSearch去修改keyword后就不会触发执行了呢? 不是很理解,应该是一样的呀
React18+TS4+Antd5+Next.js13 ,B端+C 端,完整业务
了解课程