【WEB】Antd:记一次, List 无法加载更多问题

392 阅读1分钟

题记: 最近 有一个项目升级 react18后,antd 的一个列表页突然无法加载更多了。这个列表在一个 Modal 的对话框中,带着疑问排查了后,记录下。


这是 Antd 官方的加载更多例子。

image.png

image.png

官方示例中,通过 scrollableTarget 关联了外部的 Div,通过外部 DIV 来控制监听加载更多和下拉加载的实现。

我们将官方示例放到一个 Modal 中显示,就会复现BUG 了。会发现无法触发 Next函数等问题。

通过排查,问题就出在了这个scrollableTarget。这里可以看到react-infinite-scroll-component 的源码的这一段。

image.png

image.png

可以看到组件在挂载的时候去初始化的滚动节点绑定。因为渲染顺序是 子节点的挂载后,挂载父节点。而scrollableTarget 初始化的时候,他的父DIV 还没有挂载上去,所以document.getElementById()获取到的是 null,导致了绑定失败。

知道了问题就好解决了。

解决

我们只需要确定父类 div 挂载成功后去渲染列表页就可以了。

我们将官方例子简单调整下:

const App: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<DataType[]>([]);
 
  /// 第一步: 创建一个引用
  const refScrollBody = useRef<HTMLDivElement>();

  ///======官方中间的加载函数等被删除了=========
  /// ...官方Demo这里有一些函数,
  /// https://ant-design.gitee.io/components/list-cn#components-list-demo-infinite-load
  ///=======================================
    
  return (
     //第二步:设置引用节点
    <div
      id="scrollableDiv"
      ref={refScrollBody}
      style={{
        height: 400,
        overflow: "auto",
        padding: "0 16px",
        border: "1px solid rgba(140, 140, 140, 0.35)",
      }}
    >
    //第三步:在这里判断存在父节点后渲染
    {refScrollBody.current && <InfiniteScroll
        dataLength={data.length}
        next={loadMoreData}
        hasMore={data.length < 50}
        loader={<Skeleton avatar paragraph={{ rows: 1 }} active />}
        endMessage={<Divider plain>It is all, nothing more 🤐</Divider>}
        scrollableTarget={refScrollBody.current.id}
      >
        <List
          dataSource={data}
          renderItem={(item) => (
            <List.Item key={item.email}>
              <List.Item.Meta
                avatar={<Avatar src={item.picture.large} />}
                title={<a href="https://ant.design">{item.name.last}</a>}
                description={item.email}
              />
              <div>Content</div>
            </List.Item>
          )}
        />
      </InfiniteScroll>}
    </div>
  );
};

最后,我把改动的地方圈一下。

image.png


另外,发现 github 上有一个 open 的 issue 和这个问题相关。 github.com/ankeetmaini…

好的,搞定~

Bye~