reactjs useEffect滚动到底部不起作用

k5ifujac  于 2023-02-04  发布在  React
关注(0)|答案(2)|浏览(232)

这是我的代码,测试了一个聊天机器人。当我刷新时,useEffect不工作,当接收或发送新消息时,自动滚动不工作。我错过了什么?

import './App.css';
import './normal.css';
import { useState, useRef, useEffect } from 'react';

function App() {

  const messagesEndRef = useRef(null);
  const [input, setInput] = useState("");
  const [chatLog, setChatLog] = useState([{
    user: "gpt",
    message: "Hello World"
  }])

  function clearChat(){
    setChatLog([]);
  }

useEffect(() => {
    messagesEndRef.current.scrollIntoView({ behavior: "smooth" })
  }, [chatLog]);

  async function handleSubmit(e){
    e.preventDefault();
    let chatLogNew = [...chatLog, { user: "me", message: `${input}` } ]
    await setInput("");
    setChatLog(chatLogNew)

    const messages = chatLogNew.map((message) => message.message).join("\n")

    const response = await fetch("http://localhost:3080/", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        message: messages
      })
    });
    const data = await response.json();
    setChatLog([...chatLogNew, { user: "gpt", message: `${data.message}`}])

  }

  return (
    <div className="App">
      <aside className ="sidemenu">
        <div className="title">
            <h1>Title</h1>
        </div>
        <div className="side-menu-button" onClick={clearChat}>
          <span>+</span>
          New chat
        </div>
      </aside>
      <section className="chatbox">
        <div className="chat-log">
          {chatLog.map((message, index) => (
            <ChatMessage key={index} message={message} />
          ))}
        </div>
        <div ref={messagesEndRef} />
        <div className="chat-input-holder">
            <form onSubmit={handleSubmit}>
              <input 
              rows="1"
              value={input}
              onChange={(e)=> setInput(e.target.value)}
              className="chat-input-textarea">
              </input>
            </form>
        </div>
      </section>
    </div>
  );
}

const ChatMessage = ({ message }) => {
  return (
    <div className={`chat-message ${message.user === "gpt" && "chatgpt"}`}>
            <div className="chat-message-center">
            <div className={`avatar ${message.user === "gpt" && "chatgpt"}`}>

              {message.user === "gpt" && "AI"}

              {message.user === "me" && "Me"}
              
              </div>
              <div className="message">
                {message.message}
              </div>
            </div>
          </div>
  )
}

export default App;

定义messagesEndRef并插入useEffect,然后将虚拟div放入最后呈现的消息中。
有什么想法吗?我的格式不对吗?

bybem2ql

bybem2ql1#

在useEffect()的第二个参数数组中使用[JSON.stringify(chatLog)]或chatLog.length,而不是使用chatLog

useEffect(() => {
    messagesEndRef.current.scrollIntoView({ behavior: "smooth" })
  }, [JSON.stringify(chatLog)]);
disho6za

disho6za2#

滚动进入视图选项包括:

行为(可选)

定义过渡动画。自动或平滑之一。默认为自动。

(可选)

定义垂直对齐方式。起始、居中、结束或最接近之一。默认值为起始。

内联(可选)

定义水平对齐方式。起始、居中、结束或最接近之一。默认为最接近。
所以,你需要添加块选项结束.

useEffect(() => {
    messagesEndRef.current.scrollIntoView({ behavior: "smooth", block: "end" })
  }, [chatLog]);

相关问题