切换主题
字数
511 字
阅读时间
3 分钟
让我为您解释问卷列表的渲染流程:
- 主要渲染逻辑在 List.tsx 组件中:
ts
{list.length > 0 &&
list.map((q: any) => {
const { _id } = q
return <QuestionCard key={_id} {...q} />
})}
这段代码通过 map 遍历 list 数组,为每个问卷数据渲染一个 QuestionCard 组件。
问卷数据的获取过程:
ts
const { run: load, loading } = useRequest(
async () => {
const data = await getQuestionListService({
page,
pageSize: LIST_PAGE_SIZE,
keyword,
})
return data
},
{
manual: true,
onSuccess(result) {
const { list: l = [], total = 0 } = result
setList(list.concat(l)) // 累计
setTotal(total)
setPage(page + 1)
},
}
)
使用 useRequest hook 从后端获取问卷列表数据,包含分页信息。 QuestionCard 组件的具体实现:
return (
<div className={styles.container}>
<div className={styles.title}>
<div className={styles.left}>
<Link to={isPublished ? `/question/stat/${_id}` : `/question/edit/${_id}`}>
<Space>
{isStarState && <StarOutlined style={{ color: 'red' }} />}
{title}
</Space>
</Link>
</div>
<div className={styles.right}>
<Space>
{isPublished ? <Tag color="processing">已发布</Tag> : <Tag>未发布</Tag>}
<span>答卷: {answerCount}</span>
<span>{createdAt}</span>
</Space>
</div>
</div>
每个问卷卡片包含:
标题
是否标星
发布状态
答卷数量
创建时间
列表的滚动加载功能:
const containerRef = useRef<HTMLDivElement>(null)
const { run: tryLoadMore } = useDebounceFn(
() => {
const elem = containerRef.current
if (elem == null) return
const domRect = elem.getBoundingClientRect()
if (domRect == null) return
const { bottom } = domRect
if (bottom <= document.body.clientHeight) {
load() // 真正加载数据
setStarted(true)
}
},
{
wait: 1000,
}
)
使用 useDebounceFn 实现防抖,当页面滚动到底部时加载更多数据。
主要流程是:
页面初始化时通过 getQuestionListService 获取第一页数据
数据存储在组件的 state 中
通过 map 方法将数据渲染成 QuestionCard 组件列表
当用户滚动页面时,触发加载更多数据
新数据追加到现有列表后面
重新渲染整个列表
关键特性:
支持无限滚动加载
实现了防抖优化
响应式更新
支持按关键词搜索
可以查看问卷详情、编辑、删除等操作
贡献者
sunchengzhi