简体   繁体   English

如何在聊天应用程序中单击“发送”按钮将消息滚动到底部?

[英]How to scroll messages to bottom on click on Send button in Chat App?

In a React project, I've created Chat Section.在一个 React 项目中,我创建了 Chat Section。 All designing and functionalities done, except that when messages are sent it doesn't automatically scroll down.所有设计和功能都完成了,除了发送消息时它不会自动向下滚动。 What could be the best possible solution?什么可能是最好的解决方案?

Here is the code for reference这是供参考的代码

const MessageApp = () => {
  const [textValue, setTextValue] = useState("");
  const [textMessages, setTextMessages] = useState([]);
  const [newTextValue, setNewTextValue] = useState("");
  const [showSenderMessage, setShowSenderMessage] = useState(false);
  const [showRecieverMessage, setShowRecieverMessage] = useState(false);

  useEffect(() => {
    const newData = localStorage.getItem("messages");
    setTextMessages(newData);
  }, []);

  const sendMessage = (e) => {
    e.preventDefault();

    setShowSenderMessage(true);

    if (textValue != "") {
      setTextMessages([...textMessages, textValue]);

      localStorage.setItem("messages", textMessages);
      setTextValue("");
    } else {
      return;
    }
  };

  return (
    <>
      {showSenderMessage &&
        textMessages.map((text) => (
          <div
            className="bubble-sender"
            style={{
              display: "flex",
              flexWrap: "wrap",
              justifyContent: "flex-start",
              width: "80%"
            }}
          >
            <span style={{ width: "20%" }}>
              <img
                alt="blank profile"
                src="https://cdn.business2community.com/wp-content/uploads/2017/08/blank-profile-picture-973460_640.png"
                style={{
                  height: "50px",
                  width: "50px",
                  border: "2px solid black",
                  borderRadius: "50%"
                }}
              />
            </span>

            <span style={{ width: "80%" }}>
              {text}
              <br />
              <span
                style={{
                  display: "flex",
                  flexWrap: "wrap",
                  justifyContent: "flex-end"
                }}
              >
                <small style={{ color: "grey", float: "right" }}>
                  11:23 AM
                </small>
              </span>
            </span>
          </div>
        ))}

      <span>
        <form
          style={{
            position: "fixed",
            bottom: "0",
            marginBottom: "80px",
            width: "100%"
          }}
        >
          <div className="col-lg-10 mb-3">
            <div className="input-group mycustom">
              <input
                value={textValue}
                type="text"
                required
                placeholder="Send Message"
                maxLength="30"
                onChange={(e) => setTextValue(e.target.value)}
              />
              <div className="input-group-prepend">
                <button
                  type="submit"
                  style={{
                    color: "white",
                    display: "flex",
                    flexWrap: "wrap",
                    justifyContent: "space-evenly"
                  }}
                  onClick={sendMessage}
                >
                  Send Message
                </button>
              </div>
            </div>
          </div>
        </form>
      </span>
    </>
  );
};

export default MessageApp;

Following is the codesandbox link: https://codesandbox.io/s/upbeat-montalcini-bpdsp以下是代码框链接: https://codesandbox.io/s/upbeat-montalcini-bpdsp

try this:尝试这个:

import React, { useState, useEffect, useRef } from "react";
import "./MessageApp.css";

const MessageApp = () => {
  const [textValue, setTextValue] = useState("");
  const [textMessages, setTextMessages] = useState([]);
  const [newTextValue, setNewTextValue] = useState("");
  const [showSenderMessage, setShowSenderMessage] = useState(false);
  const [showRecieverMessage, setShowRecieverMessage] = useState(false);
  const messagesEndRef = useRef(null);
  const scrollToBottom = () => {
    messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
  };
  useEffect(scrollToBottom, [textMessages]);
  useEffect(() => {
    const newData = localStorage.getItem("messages");
     setTextMessages(newData.split(","));
  }, []);

  const sendMessage = (e) => {
    e.preventDefault();

    setShowSenderMessage(true);

    if (textValue != "") {
      // const newTextValueHere = textValue;
      // setNewTextValue(newTextValueHere);
      // setTextValue("");
      setTextMessages(preVal=>[...preVal,textValue]);

      localStorage.setItem("messages", textMessages);
      setTextValue("");
    } else {
      return;
    }
  };

  return (
    <>
      {showSenderMessage &&
        textMessages.map((text) => (
          <div
            className="bubble-sender"
            style={{
              display: "flex",
              flexWrap: "wrap",
              justifyContent: "flex-start",
              width: "80%"
            }}
          >
            <span style={{ width: "20%" }}>
              <img
                alt="blank profile"
                src="https://cdn.business2community.com/wp-content/uploads/2017/08/blank-profile-picture-973460_640.png"
                style={{
                  height: "50px",
                  width: "50px",
                  border: "2px solid black",
                  borderRadius: "50%"
                }}
              />
            </span>

            <span style={{ width: "80%" }}>
              {text}
              <br />
              <span
                style={{
                  display: "flex",
                  flexWrap: "wrap",
                  justifyContent: "flex-end"
                }}
              >
                <small style={{ color: "grey", float: "right" }}>
                  11:23 AM
                </small>
              </span>
            </span>
          </div>
        ))}

      <span>
        <form
          style={{
            position: "fixed",
            bottom: "0",
            marginBottom: "80px",
            width: "100%"
          }}
        >
          <div className="col-lg-10 mb-3">
            <div className="input-group mycustom">
              <input
                value={textValue}
                type="text"
                required
                placeholder="Send Message"
                maxLength="30"
                onChange={(e) => setTextValue(e.target.value)}
              />
              <div className="input-group-prepend">
                <button
                  type="submit"
                  style={{
                    color: "white",
                    display: "flex",
                    flexWrap: "wrap",
                    justifyContent: "space-evenly"
                  }}
                  onClick={sendMessage}
                >
                  Send Message
                </button>
              </div>
            </div>
          </div>
        </form>
      </span>


      <div ref={messagesEndRef} />
    </>
  );
};

export default MessageApp;

here a sandbox based on yours ( I just remove commented code).这里是一个基于你的沙箱(我只是删除了注释代码)。
I have fixed a bug on your setTextMessages where the app return an iterator error.我已经修复了您的 setTextMessages 应用程序返回迭代器错误的错误。
You will need to make some style adjustment because for now the new message is "hide" under the input field.您将需要进行一些样式调整,因为现在新消息在输入字段下“隐藏”。

UPDATE更新

your const newData is typeOf string so you need to split it in your `setTexMessage()` like this: 您的 const newData 是 typeOf 字符串,因此您需要将其拆分为 `setTexMessage()`,如下所示:
 useEffect(() => { const newData = localStorage.getItem("messages"); setTextMessages(newData.split(",")); }, []);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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