如何在 Material-UI 对话框模式中使用 react-infinite-scroll-component?

问题描述

我在一个项目中使用 react-infinite-scroll-component 并且它在 Dialog 之外工作正常。当我滚动到页面底部时,会从服务器获取下一组数据,但我无法在 Material-UI 对话框中获得相同的操作。

这是对话代码

//imports

export default function Posts() {
  const [open,setopen] = React.useState(false);
   //more consts
   ...
  const [posts,setPosts] = useState([]);
  const [page,setPage] = useState(1);

  const fetchPosts = () => {
    axios.get(`${serverURL}/news?page=${page}`).then((res) => {
      const result = res.data.results;
      setPosts([...posts,...result]);
      setPage((prev) => prev + 1);
    });
    console.log("page",page);
  };

  useEffect(() => {
    fetchPosts();
  },[]);

  return (
    <div>
      <h1>News</h1>
      <Button variant="outlined" color="primary" onClick={handleClickOpen}>
        Open News Dialog
      </Button>
      <Dialog
        onClose={handleClose}
        aria-labelledby="customized-dialog-title"
        open={open}
      >
        <DialogTitle id="customized-dialog-title" onClose={handleClose}>
           News
        </DialogTitle>

        <DialogContent dividers>
          <ul
            style={{
              display: "inline",}}
          >
            <InfiniteScroll
              dataLength={posts.length}
              next={() => fetchPosts()}
              hasMore={true}
              loader={<h4 style={{ textAlign: "center" }}>Loading.....</h4>}
              endMessage={
                <p style={{ textAlign: "center" }}>
                  <b>You read all news posts.</b>
                </p>
              }
            >
              {posts.length > 1 &&
                posts.map((post,i) => {
                  return (
                    <div key={i}>
                      <Card className={classes.root}>
                        <div className={classes.details}>
                          <CardContent className={classes.content}>
                            <Typography
                              className={classes.title}
                              component="a"
                              variant="h5"
                            >
                              {post.title}
                            </Typography>
                            <Typography className={classes.desc}>
                                {post.content}
                            </Typography>
                          </CardContent>
                        </div>
                      </Card>
                    </div>
                  );
                })}
            </InfiniteScroll>
            );
          </ul>
        </DialogContent>
      </Dialog>
    </div>
  );
}

日志没有显示我到达了第二页,它只是在我到达后端定义的前 30 个帖子后停止。

当我在对话框外测试这段代码时,没有问题。无限滚动在这个小文本上工作正常:

function App() {
  const [posts,setPage] = useState(1);

  const fetchPosts = () => {
    axios
      .get(`${serverURL}/api/news?page=${page}`)
      .then((res) => {
        const result = res.data.results;
        setPosts([...posts,...result]);
        setPage((prev) => prev + 1);
      });
    console.log("page",[]);

  return (
    <div className="App">
      <InfiniteScroll
        dataLength={posts.length}
        next={() => fetchPosts()}
        hasMore={true}
        loader={<h4>Loading.....</h4>}
        endMessage={
          <p style={{ textAlign: "center" }}>
            <b>You read all news posts.</b>
          </p>
        }
      >
        {posts.length > 1 &&
          posts.map((post,i) => (
            <div key={i}>
              <p>{post.title}</p>
              <p>{post.image}</p>
              <p>{post.content}</p>
              <p>{post.link}</p>
            </div>
          ))}
      </InfiniteScroll>
    </div>
  );
}

export default App;

如何让无限滚动在对话框内工作?

解决方法

我可以通过将 scrollableTarget 属性添加到 DialogContent 来解决这个问题,如下所示:

<InfiniteScroll
            dataLength={posts.length}
            next={() => fetchPosts()}
            hasMore={true}
            loader={<h4 style={{ textAlign: "center" }}>Loading.....</h4>}
            endMessage={
              <p style={{ textAlign: "center" }}>
                <b>You read all new posts.</b>
              </p>
            }
            **scrollableTarget="scrollableDiv"**
          >

然后将 id="scrollableDiv" 添加到 DialogContent:

<DialogContent dividers id="scrollableDiv">
...
</DialogContent>

默认情况下,react-infinite-scroll-component 以整个窗口为目标,因此如果要将其应用于模态,则必须使用 scrollableTarget 属性以该窗口为目标。