简体   繁体   中英

Scroll from bottom to top in a text message like modal with React

I have a modal in my website where you can send and receive messages. Like Twitter DM. When I open a conversation I have to scroll to the bottom to see the most recent message but I want the conversation to open at the bottom, so the first thing I see are the most recent messages. How can I do this?

This is what I got

            <Container>
              {messages.map(message =>
                message.user.id === currentUser.id ? (
                  <div key={message.id}>
                    <p style={textAlign: 'right'}>{message.body}</p>
                  </div>
                ) : (
                  <div key={message.id}>
                    <p style={textAlign: 'left'}>{message.body}</p>
                  </div>
                )
              )}
            </Container>


const Container = styled.div`
  margin-left: 5px;
  height: 34%;
  overflow: hidden;
  overflow-y: scroll;
  height: 90%;
`;

This solution uses the latest React Hook feature, so you will need React 16.8+, and it makes use of functional components.

Here's a link to my code sandbox . The code in the sandbox is shown below.

import React, { useEffect, useRef } from "react";
import ReactDOM from "react-dom";

const styleMessageUserLabel = {
  borderRight: "1px solid black",
  padding: "0.105em 0.618em"
};

const styleMessage = {
  padding: "0.105em 0.618em"
};

function Message(props) {
  const { user, message } = props;
  return (
    <div style={{ display: "flex", margin: "0.309em" }}>
      <div style={styleMessageUserLabel}>{user}</div>
      <div style={styleMessage}>{message}</div>
    </div>
  );
}

const styleList = {
  listStyleType: "none",
  padding: 0
};
const styleItem = even => {
  return {
    padding: 0,
    margin: 0,
    background: even ? "none" : "#EFEFEF"
  };
};
function Conversation(props) {
  const { messages } = props;
  const messageList = (
    <ul style={styleList}>
      {messages.map((m, i) => (
        <li style={styleItem(i % 2 === 0)}>
          <Message user={m.user} message={m.text} />
        </li>
      ))}
    </ul>
  );
  return <div>{messageList}</div>;
}

const exampleMessages = [
  { user: "user1", text: "hey" },
  { user: "user2", text: "yo sup?" },
  { user: "user1", text: "nmu?" },
  { user: "user2", text: "chillin'" },
  { user: "user1", text: "cool cool" },
  { user: "user2", text: "what's good?" },
  { user: "user1", text: "life man" },
  { user: "user2", text: "that's what I'm talkin' 'bout" },
  { user: "user1", text: "word" },
  { user: "user2", text: "fo sho" },
  { user: "user1", text: "you down for tonight?" },
  { user: "user2", text: "we good" },
  { user: "user1", text: "solid" },
  { user: "user2", text: "cu lata" },
  { user: "user1", text: "oh, forgot to ask" },
  { user: "user2", text: "u bringin food" },
  { user: "user1", text: "pizza" },
  { user: "user2", text: "cowabunga!" },
  { user: "user1", text: "party on!" },
  { user: "user2", text: "excellent!!" },
  { user: "user1", text: "*air guitar*" },
  { user: "user2", text: "*air bass*" },
  { user: "user1", text: "*air drums*" },
  { user: "user2", text: "totally rad" },
  { user: "user1", text: "awesome" },
  { user: "user2", text: "righteous" }
];

const styleApp = {
  fontSize: "1.618em",
  fontFamily: "sans-serif"
};
function App() {
  const messagesEndRef = useRef(null);
  const scrollToBottom = () => {
    messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
  };
  useEffect(scrollToBottom, [exampleMessages]);
  return (
    <div style={styleApp}>
      <Conversation messages={exampleMessages} />
      <div ref={messagesEndRef} />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM