请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于useEffect监听searchParams的问题

图片描述

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

正在回答 回答被采纳积分+3

2回答

双越 2023-12-18 08:45:19

通过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 <Spin></Spin>;
        if (total === 0) return <Empty description="暂无数据"></Empty>;
        if (!haveMoreData) return '没有更多了...';
        return '开始加载下一页';
      }, [first,started, loading, haveMoreData]);
    我想了下,这样在初次加载时就重置的话,就可以监听到listSearch是否修改了keyword,就能直接触发执行了,就不用再 重复去单独监听keyword了,这样是不是会更好点
    回复 有任何疑惑可以回复我~ 2023-12-19 17:49:49
双越 2023-12-17 15:54:40

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


0 回复 有任何疑惑可以回复我~
  • 提问者 一如忘词 #1
    就是直接在地址栏进行修改
    回复 有任何疑惑可以回复我~ 2023-12-17 17:01:16
  • 双越 回复 提问者 一如忘词 #2
    修改以后直接回车,对吧
    回复 有任何疑惑可以回复我~ 2023-12-18 08:44:52
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信