关于useEffect监听searchParams的问题

来源:11-7 LoadMore上划加载更多-优化功能体验

一如忘词

2023-12-17

图片描述

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后就不会触发执行了呢? 不是很理解,应该是一样的呀

写回答

2回答

双越

2023-12-18

通过listSearch去修改keyword后就不会触发执行了 —— 你这样修改,看网页 url 变了没有?

0
1
一如忘词
// 页面初次加载 useEffect(() => { setPage(1); setList([]); setTotal(0); setFirst(true); tryLoadMore(); }, [searchParams]); // 监听滚动 useEffect(() => { if (haveMoreData) { setFirst(false) tryLoadMore(); } }, [inViewport, haveMoreData]); const LoadMoreContentEle = useMemo(() => { if (first || !started || loading) return ; if (total === 0) return ; if (!haveMoreData) return '没有更多了...'; return '开始加载下一页'; }, [first,started, loading, haveMoreData]); 我想了下,这样在初次加载时就重置的话,就可以监听到listSearch是否修改了keyword,就能直接触发执行了,就不用再 重复去单独监听keyword了,这样是不是会更好点
2023-12-19
共1条回复

双越

2023-12-17

手动去修改keyword —— 具体如何操作的?


0
2
双越
回复
一如忘词
修改以后直接回车,对吧
2023-12-18
共2条回复

React18+ Nest.js 全栈开发仿问卷星项目

React18+TS4+Antd5+Next.js13 ,B端+C 端,完整业务

383 学习 · 252 问题

查看课程