OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

keep div scroll to button did not work as expect in react

  • Thread starter Thread starter Dolphin
  • Start date Start date
D

Dolphin

Guest
I have a react component like this(the nodejs version is 18):

Code:
import { ISseMsg } from "@/models/chat/SseMsg";
import withConnect from "@/page/component/hoc/withConnect";
import { v4 as uuid } from "uuid";
import React, { useRef, useState } from "react";
import ChatContext from "./ChatContext";
import chatMeImage from "@/asset/icon/chat-me.png";
import chatgpt from "@/asset/icon/chatgpt.svg";
import "./ChatList.css";
import { isSubscribed } from "@/service/user/UserService";
import { useSelector } from "react-redux";
import { BaseMethods } from "rdjs-wheel";

export interface IChatAskList {
  myMap: Map<string, ISseMsg>;
}

/**
 * when the chat list increase, the chat list will rerender every time when user input words
 * so add the React.memo to avoid the dulplicate rerender
 */
const ChatList: React.FC<IChatAskList> = React.memo((props) => {
  const [subscribed, setSubscribed] = useState(isSubscribed() || false);
  const { user } = useSelector((state: any) => state.user);
  const messagesEndRef = useRef(null);

  React.useEffect(() => {
    // debugger
    scrollToBottom();
  }, [props.myMap]);

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
  }

  React.useEffect(() => {
    if (!BaseMethods.isNull(user)) {
      if (Number(user.autoRenewProductExpireTimeMs) > new Date().getTime()) {
        setSubscribed(true);
      }
    }
  }, [user]);

  

  const renderChat = () => {
    const tagList: JSX.Element[] = [];
    if (props.myMap.size === 0 && !subscribed) {
      // return newGuide();
    } else if (props.myMap.size === 0 && subscribed) {
      // return genieHomeGuide();
    } else {
      props.myMap.forEach((value, key) => {
        let chatValue: ISseMsg = value;
        if (value.type === "prompt") {
          tagList.push(
            <div key={uuid()} className="chat-message">
              <img alt="" className="chat-me" src={chatMeImage}></img>
              <ChatContext msg={chatValue.msg}></ChatContext>
            </div>
          );
        } else {
          tagList.push(
            <div key={uuid()} className="chat-message">
              <img alt="" className="chat-me" src={chatgpt}></img>
              <ChatContext msg={chatValue.msg}></ChatContext>
            </div>
          );
        }
      });
      return tagList;
    }
  };

  return (
    <div className="chat-list-body">
      <button onClick={scrollToBottom}>Scroll to Button</button>
      {renderChat()}
      <div ref={messagesEndRef} />
    </div>
  );
});
export default withConnect(ChatList);

now I want the chat-list-body div always scroll to button when props.myMap changed. I have tried to add useEffect like this:

Code:
React.useEffect(() => {
    // debugger
    scrollToBottom();
  }, [props.myMap]);

I also tried to add a button, when click the button, chat-list-body scroll to button works, and will scroll to top when props.myMap changed. How to make the chat-list-body div always scroll to button? Am I missing something?

<p>I have a react component like this(the nodejs version is 18):</p>
<pre><code>import { ISseMsg } from "@/models/chat/SseMsg";
import withConnect from "@/page/component/hoc/withConnect";
import { v4 as uuid } from "uuid";
import React, { useRef, useState } from "react";
import ChatContext from "./ChatContext";
import chatMeImage from "@/asset/icon/chat-me.png";
import chatgpt from "@/asset/icon/chatgpt.svg";
import "./ChatList.css";
import { isSubscribed } from "@/service/user/UserService";
import { useSelector } from "react-redux";
import { BaseMethods } from "rdjs-wheel";

export interface IChatAskList {
myMap: Map<string, ISseMsg>;
}

/**
* when the chat list increase, the chat list will rerender every time when user input words
* so add the React.memo to avoid the dulplicate rerender
*/
const ChatList: React.FC<IChatAskList> = React.memo((props) => {
const [subscribed, setSubscribed] = useState(isSubscribed() || false);
const { user } = useSelector((state: any) => state.user);
const messagesEndRef = useRef(null);

React.useEffect(() => {
// debugger
scrollToBottom();
}, [props.myMap]);

const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
}

React.useEffect(() => {
if (!BaseMethods.isNull(user)) {
if (Number(user.autoRenewProductExpireTimeMs) > new Date().getTime()) {
setSubscribed(true);
}
}
}, [user]);



const renderChat = () => {
const tagList: JSX.Element[] = [];
if (props.myMap.size === 0 && !subscribed) {
// return newGuide();
} else if (props.myMap.size === 0 && subscribed) {
// return genieHomeGuide();
} else {
props.myMap.forEach((value, key) => {
let chatValue: ISseMsg = value;
if (value.type === "prompt") {
tagList.push(
<div key={uuid()} className="chat-message">
<img alt="" className="chat-me" src={chatMeImage}></img>
<ChatContext msg={chatValue.msg}></ChatContext>
</div>
);
} else {
tagList.push(
<div key={uuid()} className="chat-message">
<img alt="" className="chat-me" src={chatgpt}></img>
<ChatContext msg={chatValue.msg}></ChatContext>
</div>
);
}
});
return tagList;
}
};

return (
<div className="chat-list-body">
<button onClick={scrollToBottom}>Scroll to Button</button>
{renderChat()}
<div ref={messagesEndRef} />
</div>
);
});
export default withConnect(ChatList);

</code></pre>
<p>now I want the <code>chat-list-body</code> div always scroll to button when <code>props.myMap</code> changed. I have tried to add useEffect like this:</p>
<pre><code>React.useEffect(() => {
// debugger
scrollToBottom();
}, [props.myMap]);
</code></pre>
<p>I also tried to add a button, when click the button, <code>chat-list-body</code> scroll to button works, and will scroll to top when <code>props.myMap</code> changed. How to make the <code>chat-list-body</code> div always scroll to button? Am I missing something?</p>
 

Latest posts

B
Replies
0
Views
1
Blundering Ecologist
B
Top