TIL

2024.04.19 TIL #์ฑ„ํŒ… #๋งˆ์ง€๋ง‰_๋ฉ”์„ธ์ง€_๊ธฐ์–ต #์—ฌ๊ธฐ๊นŒ์ง€_์ฝ์—ˆ์Šต๋‹ˆ๋‹ค

inz1234 2024. 5. 9. 23:32

๐Ÿ“Œ Task TODOLIST

- [x] ๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€ ์ €์žฅํ•˜๋Š” table ๋งŒ๋“ค๊ธฐ

- [x] ์ปดํฌ๋„ŒํŠธ mount ์‹œ ์ด์ „ ๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€ ๊ฐ•์กฐ์ฒ˜๋ฆฌ

- [x] ์ปดํฌ๋„ŒํŠธ unmount ์‹œ ๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€ ๊ธฐ์–ต


โœจ ๊ฐœ๋ฐœ ๋‚ด์šฉ

1. ๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€ ์ €์žฅํ•˜๋Š” table ๋งŒ๋“ค๊ธฐ

Why(์ด์œ )

๊ธฐ์กด ์ฑ„ํŒ…๊ณผ ๊ด€๋ จ๋œ messages์™€ chatting_room ์ด๋ผ๋Š” 2๊ฐœ์˜ table์ด ์žˆ์—ˆ์ง€๋งŒ,

๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€๋Š” ์œ ์ €๋งˆ๋‹ค ๊ณ ์œ ํ•˜๊ณ  ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ์šด table์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒŒ ๋‚ซ๋‹ค๋Š” ํŒ๋‹จ

 

what(๊ฒฐ๊ณผ) 

remember_last_msg๋ผ๋Š” table์„ ๋งŒ๋“ค๊ณ  ๊ตฌ์„ฑ์š”์†Œ์™€ ๊ฐ type์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑํ–ˆ๋‹ค. 

 

2. ์ปดํฌ๋„ŒํŠธ mount ์‹œ ์ด์ „ ๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€ ๊ฐ•์กฐ์ฒ˜๋ฆฌ

Why(์ด์œ )

๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ทธ ๋ฉ”์„ธ์ง€์— ๋ฐฐ๊ฒฝ์ƒ‰ ์ž…ํžˆ๊ธฐ + ํ•˜๋‹จ์— ๋ฌธ๊ตฌ ์ถ”๊ฐ€ + ํ•ด๋‹น div๊นŒ์ง€ ์Šคํฌ๋กค ํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค.

 

How(๊ณผ์ •)

(1) useEffect ์˜ ์˜์กด์„ฑ ๋ฐฐ์—ด์„ ๋นˆ ๋ฐฐ์—ด๋กœ ํ•˜์—ฌ ์ฒ˜์Œ mount ์‹œ, DB์— ์ €์žฅ๋œ ๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€์˜ id์™€ ์ผ์น˜ํ•˜๋Š” ๋ฉ”์„ธ์ง€ div๋ฅผ ๊ฐ•์กฐ์ฒ˜๋ฆฌ ํ•œ๋‹ค. 

(2) ๊ฐ•์กฐ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด์„œ๋Š” ๊ฐ ๋ฉ”์„ธ์ง€์˜ ์ฐธ์กฐ๊ฐ€ ํ•„์š”ํ–ˆ๋‹ค. useRef๋กœ messages๋ฅผ ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ๋„ฃ์€ ๋’ค,

๊ฐ ๋ฉ”์„ธ์ง€ div์— ref๊ฐ’์„ ๋ถ€์—ฌํ•œ๋‹ค.

const lastDivRefs = useRef(messages);


const ChatList = ({ user, chatRoomId }: { user: User | null; chatRoomId: string }) => {
  return (
    <>
 {messages &&
          messages.map((msg, idx) => (
            <div key={msg.message_id} className="w-full">
              {isNextDay(idx, messages) ? (
                <div className="flex justify-center my-[16px] bg-[#D4D4D8] mx-auto w-36 px-[16px] py-[6px] rounded-full text-white">
                  <p className="font-extralight tracking-wide text-sm">{showingDate(msg.created_at)}</p>
                </div>
              ) : null}
              {msg.send_from === user?.id ? (
                <MyChat msg={msg} idx={idx} lastDivRefs={lastDivRefs} /> -----> *
              ) 


const MyChat = ({ msg, idx, lastDivRefs }: { msg: Message; idx: number; lastDivRefs: any }) => {
  return (
    <>
    // ๊ฐ div์— ref๊ฐ’ ๋ถ€์—ฌ
      <div id={msg.message_id} ref={lastDivRefs.current[idx]} className="flex gap-[8px] justify-end">
        <div className="w-80 flex flex-col gap-1">
        ...

 

(3) ์žˆ์œผ๋ฉด ํ•ด๋‹น ๋ฉ”์„ธ์ง€๋ฅผ ๊ฐ•์กฐ์ฒ˜๋ฆฌํ•œ๋‹ค.

๋งŒ์•ฝ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ฝ์€ ๋ฉ”์„ธ์ง€๊ฐ€ ์‹ค์ œ ๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€๋ผ๋ฉด ๊ฐ•์กฐ์ฒ˜๋ฆฌ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋งŒ์•ฝ ๋‚ด๊ฐ€ ์ฐพ๋Š” ๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€์˜ id๊ฐ€ ํ™”๋ฉด์— ์—†๋‹ค๋ฉด ๊ทธ๋ƒฅ ์Šคํฌ๋กค ๋‹ค์šด.

  // ์—ฌ๊ธฐ๊นŒ์ง€ ์ฝ์œผ์…จ์Šต๋‹ˆ๋‹ค(์ฒ˜์Œ ๋งˆ์šดํŠธ ์‹œ์—๋งŒ ์‹คํ–‰)
  useEffect(() => {
    const scrollBox = scrollRef.current;
    if (scrollBox && messages) {
      // DB์— ๋งˆ์ง€๋ง‰ ๋ฉ”์„ธ์ง€๋กœ ์ €์žฅ๋œ ๋ฉ”์„ธ์ง€์™€ id๊ฐ€ ๋™์ผํ•œ div ๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ฐ•์กฐ์ฒ˜๋ฆฌ
      const lastMsgValue = lastDivRefs?.current?.find((ref) => ref.message_id === lastMsgId);
      const lastDiv = lastMsgValue && (lastMsgValue as any).current;
      if (lastMsgId && lastMsgId !== messages[messages.length - 1].message_id && lastDiv) {
        setLastCheckedDiv(lastDiv);
        styleHere(lastDiv);
        setIsScrolling(true);
      } else {
        // ๊ทธ ์™ธ์˜ ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ ์œผ๋กœ ์Šคํฌ๋กค ๋‹ค์šด
        scrollBox.scrollTop = scrollBox.scrollHeight;
        setCheckedLastMsg(true);
      }
    }
  }, [lastMsgId]);
  
    const styleHere = (lastDiv: HTMLElement) => {
    lastDiv.style.backgroundColor = '#F2EAFA';
    lastDiv.style.borderRadius = '5px';
    lastDiv.scrollIntoView({ block: 'center' });
  };

 

๐Ÿšจ  TroubleShotting

(1) ์ฒ˜์Œ mount ์‹œ ์—ฌ๊ธฐ๊นŒ์ง€ ์ฝ์œผ์…จ์Šต๋‹ˆ๋‹ค ๊ฐ•์กฐ์ฒ˜๋ฆฌ๋ฅผ ๋ณด๊ณ , ๋‚ด๊ฐ€ ์Šคํฌ๋กค ๋‹ค์šด์„ ํ•˜์ง€๋„ ์•Š์•˜๋Š”๋ฐ ์Šคํฌ๋กค ๋‹ค์šด์ด ๋˜์–ด๋ฒ„๋ฆฌ๋Š” ์ด์Šˆ๊ฐ€ ์žˆ์—ˆ๋‹ค.

Why(์ด์œ )

๊ฐ•์กฐ์ฒ˜๋ฆฌ๊ฐ€ ๋œ ๊ฑธ ๋ณด๊ณ  ๋‚ด๊ฐ€ ์Šคํฌ๋กค๋‹ค์šด ํ•˜๋Š” ๊ทธ ์‚ฌ์ด์˜ ์‹œ๊ฐ„์„ ์žก์•„์ค„ state๊ฐ€ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ•์กฐ์ฒ˜๋ฆฌ์™€ ์Šคํฌ๋กค ๋‹ค์šด์ด ์ˆœ์ฐจ์ ์œผ๋กœ ์ž๋™์œผ๋กœ ์‹คํ–‰๋œ ๊ฒƒ์ด ์›์ธ์ด์—ˆ๋‹ค. 

How(๊ณผ์ •)

checkedLastMsg ๋ผ๋Š” state๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์„œ, ์—ฌ๊ธฐ๊นŒ์ง€ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค ๊ฐ•์กฐ์ฒ˜๋ฆฌ๋ฅผ ํ™•์ธํ–ˆ๋Š”์ง€ ํŒ๋‹จํ•˜๊ณ ,

์Šคํฌ๋กค ๋‹ค์šด์„ ํ•˜๋Š” ๊ทธ ์‚ฌ์ด ์‹œ์ ์„ ์ปจํŠธ๋กค ํ–ˆ๋‹ค.

  const [checkedLastMsg, setCheckedLastMsg] = useState(false); 
 
 // ์Šคํฌ๋กค ๋‹ค์šด
  useEffect(() => {
    const scrollBox = scrollRef.current;
    if (!isScrolling && messages) {
      // ๋งˆ์ง€๋ง‰์œผ๋กœ ์ฝ์€ ๋ฉ”์„ธ์ง€(lastCheckedDiv)๊ฐ€ ํ™”๋ฉด์— ์žˆ์„ ๋•Œ
      if (lastCheckedDiv) {
        // ๊ฐ•์กฐ์ฒ˜๋ฆฌ๋ฅผ ๋ณด๊ณ ๋‚œ ๋’ค ์Šคํฌ๋กค์„ ๋งจ ์•„๋ž˜๋กœ ๋‚ด๋ฆฌ๋ฉด ๊ฐ•์กฐ์ฒ˜๋ฆฌ ํ•ด์ œ
        if (!checkedLastMsg) {
          setCheckedLastMsg(true);
          lastCheckedDiv.style.backgroundColor = '';
        } else if (checkedLastMsg && prevMsgsLengthRef.current !== messages.length) {
          // ๊ฐ•์กฐ์ฒ˜๋ฆฌ๋ฅผ ๋ณด๊ณ ๋‚˜์•ผ๋งŒ ํƒ€์ธ์œผ๋กœ๋ถ€ํ„ฐ ์ƒˆ๋กœ์šด ๋ฉ”์„ธ์ง€๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์„ ๋•Œ ์Šคํฌ๋กค ๋‹ค์šด๋˜๋„๋ก
          scrollBox.scrollTop = scrollBox.scrollHeight;
          prevMsgsLengthRef.current = messages.length;
        }
      } else if (prevMsgsLengthRef.current !== messages.length || count === 0) {
        // ์ด์ „ ๋ฉ”์„ธ์ง€๊ฐ€ ํ™”๋ฉด์— ์—†๊ณ  + ์ƒˆ๋กœ์šด ๋ฉ”์„ธ์ง€๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด ์Šคํฌ๋กค ๋‹ค์šด์ด ๋”ฐ๋ผ๊ฐ€๋„๋ก
        scrollBox.scrollTop = scrollBox.scrollHeight;
        prevMsgsLengthRef.current = messages.length;
      }
    }
  }, [messages, isScrolling]);

 

๐Ÿ“ธ ์Šคํฌ๋ฆฐ์ƒท

 

๊ฒฝ์šฐ์˜ ์ˆ˜ ์ง€์˜ฅ์ด์—ˆ๋‹ค.....

์•„์˜ค ๋จธ๋ฆฌ์•ผ..