【问题标题】:How to scroll messages to bottom on click on Send button in Chat App?如何在聊天应用程序中单击“发送”按钮将消息滚动到底部?
【发布时间】:2021-03-07 16:46:32
【问题描述】:

在一个 React 项目中,我创建了聊天部分。所有设计和功能都完成了,除了发送消息时它不会自动向下滚动。什么是最好的解决方案?

这里是参考代码

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;

下面是codeandbox链接:https://codesandbox.io/s/upbeat-montalcini-bpdsp

【问题讨论】:

  • 这个answer可以帮助你
  • 好的,但是我将 'scrollIntoView' 设为 null

标签: javascript css reactjs


【解决方案1】:

试试这个:

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;

这里是基于您的sandbox(我只是删除了注释代码)。
我已经修复了您的 setTextMessages 上的一个错误,该错误导致应用返回迭代器错误。
您需要进行一些样式调整,因为现在新消息在输入字段下是“隐藏”的。

更新

你的 const newData 是 typeOf 字符串,所以你需要像这样在你的`setTexMessage()` 中拆分它:
 useEffect(() => {
    const newData = localStorage.getItem("messages");

    setTextMessages(newData.split(","));
   }, []);

【讨论】:

    猜你喜欢
    • 2020-09-03
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    相关资源
    最近更新 更多