最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Scroll to the last item of a mapped array - Stack Overflow

programmeradmin1浏览0评论

I have a Message ponent that displays all the messages(ining and outgoing) in one thread.

I would like the last message/a newly typed message/ining message to always appear at the bottom of the conversation. Kind of like what all chats/messaging apps do.

Here is my code:

import React, { useRef } from "react";

const dummy = useRef();

...

dummy?.current?.scrollIntoView(true, {
    behaviour: "auto",
});

... 

<div className="">
  <Paper
    elevation={0}
    sx={{
      backgroundColor: "#fafafa",
      maxHeight: 200,
      overflow: "auto",
    }}
  >
    {messages.map((message, idx) => (
      <div key={idx} ref={dummy}>
        <Message message={message} name={name} />
      </div>
    ))}
    {/* I tried this also
    <div ref={dummy}></div> */}
  </Paper>
</div>

I want all the messages that can fit in the parent div with maxHeight: 200 to be displayed with the last message just at the bottom when I click on the conversation/thread. Currently, the WHOLE page scrolls to bottom instead of just the messages in the thread. The page should remain stationary.

How do I do this?

I have a Message ponent that displays all the messages(ining and outgoing) in one thread.

I would like the last message/a newly typed message/ining message to always appear at the bottom of the conversation. Kind of like what all chats/messaging apps do.

Here is my code:

import React, { useRef } from "react";

const dummy = useRef();

...

dummy?.current?.scrollIntoView(true, {
    behaviour: "auto",
});

... 

<div className="">
  <Paper
    elevation={0}
    sx={{
      backgroundColor: "#fafafa",
      maxHeight: 200,
      overflow: "auto",
    }}
  >
    {messages.map((message, idx) => (
      <div key={idx} ref={dummy}>
        <Message message={message} name={name} />
      </div>
    ))}
    {/* I tried this also
    <div ref={dummy}></div> */}
  </Paper>
</div>

I want all the messages that can fit in the parent div with maxHeight: 200 to be displayed with the last message just at the bottom when I click on the conversation/thread. Currently, the WHOLE page scrolls to bottom instead of just the messages in the thread. The page should remain stationary.

How do I do this?

Share Improve this question edited Apr 16, 2022 at 4:52 Youzef asked Apr 15, 2022 at 19:58 YouzefYouzef 8582 gold badges10 silver badges27 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 13 +50

The problem is you are passing the ref to the div element in which the Message ponent is rendered. I would suggest you use a dummy div at the end of your chat and then scroll to that whenever your ponent is updated.

return (
    <div
      className="messagesWrapper"
      style={{ background: "white", border: "2px red solid" }}
    >
      {messages.map((message) => (
        <span key={message}>{message}</span>
      ))}
      <div ref={dummy} />
    </div>
  );

The ref element is updated in useEffect.

const dummy = useRef(null);
useEffect(() => {
  dummy.current.scrollIntoView({ behavior: "smooth" });
}, [messages]);

Attaching a sandbox for reference.

I think this will work:

React.useEffect(() => {
    dummy.current.scrollTop = dummy.current.scrollHeight
})

So what you can do is create a useRef and then initiate it as null

Then when you .map over your array to render the objects, run a function to check if it's the last item in the array

If it is the last object in the array, attach the ref to it

Then have a useEffect with the ref in the dependency array

If the useRef get's set with a new value, from the .map,in your useEffect, have a scrollTo behavior, smooth, function that scrolls to it

发布评论

评论列表(0)

  1. 暂无评论