๐Ÿ“Œย ์ฃผ์š” ๊ธฐ๋Šฅ

  1. ์ƒํƒœ ๊ด€๋ฆฌ (State)
  2. IntersectionObserver๋ฅผ ํ™œ์šฉํ•œ ์„น์…˜ ๊ฐ์ง€
  3. ์Šคํฌ๋กค ๊ฐ์ง€๋กœ Top ๋ฒ„ํŠผ ํ‘œ์‹œ
  4. ๋ Œ๋”๋ง ๊ตฌ์กฐ - ๊ฐ ์„น์…˜์„ ๊ตฌ๋ถ„ํ•ด์„œ ๋ถ€๋“œ๋Ÿฌ์šด ์ด๋™ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ •

<aside> ๐Ÿ’ฌ

const [activeSection, setActiveSection] = useState('');
const [showButton, setShowButton] = useState(false);

  useEffect(() => {
    const sections = document.querySelectorAll('section');

    // ํŠน์ • ์„น์…˜์ด ํ™”๋ฉด์— 10% ์ด์ƒ ๋“ค์–ด์˜ค๋ฉด ๊ฐ์ง€๋˜๋„๋ก IntersectionObserver ์„ค์ •
    const observerOptions = {
      root: null,
      threshold: 0.1,
    };

    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          setActiveSection(entry.target.id);
        }
      });
    }, observerOptions);

    // dom์„ ํ†ตํ•ด ๊ฐ€์ ธ์˜จ ์„น์…˜ ์š”์†Œ๋“ค์„ ๊ด€์ฐฐ ๋Œ€์ƒ์œผ๋กœ ๋“ฑ๋กํ•จ
    sections.forEach((section) => {
      observer.observe(section);
    });

    return () => {
      sections.forEach((section) => observer.unobserve(section));
    };
  }, []);

</aside>

<aside> ๐Ÿ’ฌ

// ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋จ (์Šคํฌ๋กค ๊ฐ์ง€ ์„ค์ •์€ ํ•œ ๋ฒˆ๋งŒ ํ•„์š”ํ•˜๋‹ˆ๊นŒ)
useEffect(() => {
  const handleScroll = () => {
    if (window.scrollY > 340) {
      setShowButton(true);    // ๋ฒ„ํŠผ ๋ณด์ด๊ธฐ
    } else {
      setShowButton(false);   // ๋ฒ„ํŠผ ์ˆจ๊ธฐ๊ธฐ
    }
  };

  // ์Šคํฌ๋กค ์ด๋ฒคํŠธ ๊ฐ์ง€ ์‹œ์ž‘
  window.addEventListener("scroll", handleScroll);

  // ์ปดํฌ๋„ŒํŠธ ์‚ฌ๋ผ์งˆ ๋•Œ ์ด๋ฒคํŠธ ์ œ๊ฑฐ
  return () => {
    window.removeEventListener("scroll", handleScroll);
  };
}, []); // []๋ฅผ ๋„ฃ์–ด์„œ useEffect๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰์‹œํ‚ด

</aside>

<aside> ๐Ÿ’ฌ

return (
   <>
      <Header activeSection={activeSection} />
      <main className="relative">
        <IntroSection />

        <section id="about">
          <AboutSection />
        </section>

        <section id="stack">
          <StackSection />
        </section>

        <section id="project">
          <ProjectSection />
        </section>

        <section id="contact">
          <ContactSection />
        </section>
      </main>

      <TopButton showButton={showButton} />
    </>
  );
};

</aside>