ant-design-mobile icon indicating copy to clipboard operation
ant-design-mobile copied to clipboard

希望InfiniteScroll能增加loading属性

Open chenliangngng opened this issue 3 years ago • 12 comments

Version of antd-mobile

v5.0.0-rc.21

What is this feature about?

目前loading状态是通过loadMore函数确定的,希望直接传入loading来进行更高优先级控制

chenliangngng avatar Jan 25 '22 09:01 chenliangngng

可以具体描述一下你的使用场景么?比较好奇在什么情况下需要用这个额外的 loading 属性来手动控制

我觉得加不加 loading 属性是其次的,重要是找到当前 API 使用起来不那么方便的场景,然后再看看这个场景存在的问题通过什么方式来解决才是最合理的,未必是加个 loading 属性这么简单

awmleer avatar Jan 27 '22 03:01 awmleer

调用下一页的动作,不是直接调用promise接口,而是写在useEffect里面。比如点击下一步,修改了currentPage,触发setSearchParams,然后由于searchParams变化,触发接口函数

const [searchParams, setSearchParams] = useState()
useEffect((
)=>{
// fetch
},[searchParams])

@awmleer

chenliangngng avatar Jan 27 '22 03:01 chenliangngng

@chenliangngng OK 了解了

不过我还有个小疑惑哈,假如说我们给 InfiniteScroll 增加了 loading 属性,那你会怎么使用 loading 属性来解决这个场景的问题呢?可以再写一下 demo 么

awmleer avatar Jan 27 '22 04:01 awmleer

@chenliangngng OK 了解了

不过我还有个小疑惑哈,假如说我们给 InfiniteScroll 增加了 loading 属性,那你会怎么使用 loading 属性来解决这个场景的问题呢?可以再写一下 demo 么

const [searchParams, setSearchParams] = useState()
const [loading, setLoading] = useState()
useEffect(()=>{
  try{
    setLoading(true)
    // fetch
  } finally {
    setLoading(false)
  }
},[searchParams])

chenliangngng avatar Feb 08 '22 07:02 chenliangngng

get,其实现在的问题是 InfiniteScroll 对于手动数据加载的情况不太适用,我再想一下怎么处理比较好

awmleer avatar Feb 08 '22 08:02 awmleer

这种场景之前的确也有其他社区同学提到过

awmleer avatar Feb 08 '22 08:02 awmleer

有两个方案可以参考: 1、支持ref,自定义发起加载更多,并自带loading:

type InfiniteScrollRef = {
    loadMore: (customLoadMoreFn?: () => Promise<unknow>) => void;
}

function C(){
   const ref = useRef<InfiniteScrollRef>(null);
   async function loadMore(){
      // fetch1
   }
   return <>
      <Button onClick={() => {
            //调用InfiniteScroll自身loadMore
            ref.current.loadMore();
            // 需要自定义加载则入参
            ref.current.loadMore(async function(){
                 // fetch2
            });
       }}>点击加载更多</Button>
      <List>...</List>
      <InfiniteScroll loadMore={loadMore} />
   </>
}

2、给InfiniteScroll组件增加优先级更高的loading属性,不传时则组件内部控制,传入时则完全受控。

xiaoyao96 avatar Feb 11 '22 08:02 xiaoyao96

做成一个属性来切换受控非受控感觉有点太恶心了,而且用户用起来设想了一下感觉也不省事

或许可以这样通过 ref 来手动控制:

const infiniteScrollRef = useRef()

async function doRequest() {
  infiniteScrollRef.current.startManualTask()
  try {
    await api.myRequest(pageCount)
    infiniteScrollRef.current.finishManualTask()
  } catch (e) {
    infiniteScrollRef.current.failManualTask()
  }
}

useEffect(() => {
  doRequest()
}, [pageCount])

<InfiniteScroll
  ref={infiniteScrollRef}
  loadMore={(isRetry) => {
    if (isRetry) {
      doRequest()
    } else {
      setPageCount(v => v + 1)
    }
  }}
/>

上面的 demo 看起来有点复杂,是因为同时考虑到了请求异常的处理

awmleer avatar Jun 08 '22 09:06 awmleer

@awmleer startManualTask() 这个方法,需要干什么? 要区分出手动加载数据吗?

zqran avatar Sep 19 '22 03:09 zqran

@zqran 当时我设想的是,有两套状态,分别是手动模式和自动模式对应的 hasMore failed 之类的状态,然后手动模式的优先级更高,不过感觉可能也不好实现?

感觉还是得再从具体的 case 出发,才能知道哪种 API 设计是最合理的

awmleer avatar Sep 20 '22 03:09 awmleer

@awmleer 可以再参考下 #5653 中 @mnm1001 的回复

zqran avatar Sep 20 '22 07:09 zqran

OK~回复了

awmleer avatar Sep 20 '22 08:09 awmleer