【问题标题】:Adding a div to the bottom of a list view pushes all view upward out of viewport将 div 添加到列表视图的底部会将所有视图向上推出视口
【发布时间】:2022-01-02 23:18:54
【问题描述】:

我正在React 中实现一个聊天视图,期望的行为是每当新数据被推入dataSource 时,聊天视图(无限列表)滚动到底部,有很多实现,一些在这里找到:How to scroll to bottom in react?。但是,当我尝试实现它时,我得到了这种奇怪的行为,窗口中的所有视图都被“向上推”了大约 300 像素,好像是为了适应列表底部的这个新 <div>看法。我的实现如下:

        import React, {useEffect, useRef} from "react";
        import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
        import InfiniteScroll from 'react-infinite-scroll-component';


        const row_1 = 2.5;
        const row_chat = 4

        const useStyles = makeStyles((theme: Theme) => createStyles({

            container: {
                width: '40vw',
                height: `calc(100vh - 240px)`,
                position: 'relative',
                padding: theme.spacing(3),  
            },

        }));


        const chat_container_style = {
            width: '40vw',
            height: `calc(100vh - 240px - ${row_chat}vh - ${row_1}vh)`,
        }




        function ChatView(props) {

            const classes = useStyles();
            const { _dataSource } = props;

            // scroll to bottom
            const messagesEndRef = useRef(null)
            const scrollToBottom = () => {
                messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
            }
            useEffect(() => {
                scrollToBottom()
            }, [_dataSource]);


            return (
                <div className={classes.container}>


                    {/* chat window */}
                    <InfiniteScroll
                        dataLength={_dataSource.length}
                        next={() => { return }}
                        hasMore={true}
                        loader={<></>}
                        style={chat_container_style}
                    >
                        {_dataSource.map((item, index) => {
                            return (
                                 <div {...props} key={index} item={item}>
                                    {`item: ${index}`}
                                 </div>
                            )
                        })}

                        {/* putting an item here push all divs upward */}
                        <div ref={messagesEndRef} />
                    </InfiniteScroll>


                </div>
            )


        }




注意&lt;InfiniteScroll/&gt; 的使用不是导致该行为的原因,真的,如果我将ref={messagesEndRef} 放入任何视图,它会将所有视图推到视口中。

【问题讨论】:

  • 我意识到答案实际上是因为scrollIntoView函数,问题在这里解决:stackoverflow.com/questions/11039885/…
  • 所以这个问题是重复的?我们应该删除它,还是您可以自己回答?
  • @kca 我会回答的。我提供的任何资料都没有完全解决这个具体问题。人们赞成它,所以我想它很有用

标签: javascript reactjs


【解决方案1】:

问题已解决。问题的根源是scrollIntoView 函数,它滚动整个页面而不是仅仅滚动listView,这是正确的scrollIntoView 函数和正确的参数:

    const scrollDivRef = createRef();
    useEffect(() => {
        scrollDivRef.current?.scrollIntoView({
            block   : 'nearest',
            inline  : 'start',
            behavior: 'smooth',
        })
    }, [_dataSource.length]);

下面是 ref 嵌套在 DOM 中的方式:

            <InfiniteScroll
                next={() => { return }}
                hasMore={true}
                loader={<></>}
                style={chat_container_style}
                dataLength={_dataSource.length}
            >   
                {_dataSource.map((item, index) => (
                    <BubbleView {...props} key={index} item={item}/>
                ))}
                <div style={refDivStyle} ref={scrollDivRef}/>
            </InfiniteScroll>

这个问题与我如何布局样式表无关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多