2

I am implementing a chat view in React,and the desired behavior is that whenever new data is pushed into the dataSource, the chat view (an infinite list) scrolls to the bottom, there are many implementations, some found here: How to scroll to bottom in react?. However when I try to implement it, I am getting this strange behavior where all the views in the window are "pushed upward" out of sight by some 300px, as if to accomadate this new <div> that is at the bottom of the list view. My implementation below:

        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>
            )


        }




Note the use of <InfiniteScroll/> is not the cause of the behavior, Really if I put the ref={messagesEndRef} into any view, it pushes all the views up in the viewport.

xiaolingxiao
  • 4,793
  • 5
  • 41
  • 88
  • I realized the answer is actually becuase of the `scrollIntoView` function, the issue is resolved here: https://stackoverflow.com/questions/11039885/scrollintoview-causing-the-whole-page-to-move – xiaolingxiao Jan 03 '22 at 02:23
  • so this question is a duplicate ? Should we delete it, or can you answer it yourself ? – kca Jan 03 '22 at 07:59
  • @kca I'll answer it. Neither of the sources I provided address this specific issue in its entirrety. and people upvoted it so i guess it's useful – xiaolingxiao Jan 03 '22 at 15:16

1 Answers1

1

The issue has been resolved. The source of the issue is the scrollIntoView function, it's scrolling the entire page instead of just the listView, here's the correct scrollIntoView function with the correct parameters:

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

Here's how the ref is nested inside the 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>

This problem has nothing to do w/ how I layout the style sheet.

xiaolingxiao
  • 4,793
  • 5
  • 41
  • 88