0

I am trying to navigate(scroll) the one pager with onClick function in header, and at the same time have functionality to change navlink active classname while scrolling the page. When I reach the scroll position of About section, navlink About should get active class.

The problem is I get the scroll to work but then I can't use navlink onClick function. It changes the state for milisecond and goes back to the previous.

I need instructions to achieve this and I guess there is a solution but I did not think it up very well. If you can redirect me to a tutorial for achieving this functionality or tell me what should I do to make it correctly.

Thank you very much!

App.js

import React, { useEffect, useRef, useState } from "react";
import Header from "./components/Header";
import "./App.scss"
import About from "./sections/About";
import Home from "./sections/Home";
import Projects from "./sections/Projects";

function App() {
    const [scrollState, setScrollState] = useState("home")
    const homeRef = useRef(null);
    const aboutRef = useRef(null);
    const projectsRef = useRef(null);

    const handleNavScroll = (e) => {
        setScrollState(e)
    }

    const handleScroll = () => {

        const homeOffset = homeRef.current.offsetTop;
        const aboutOffset = aboutRef.current.offsetTop;
        const projectsOffset = projectsRef.current.offsetTop;
        const scrollPosition = window.scrollY;

        if (
            scrollPosition >= homeOffset &&
            scrollPosition < aboutOffset &&
            scrollState !== "home"
        ) {
            setScrollState("home");
        } else if (
            scrollPosition >= aboutOffset &&
            scrollPosition < projectsOffset &&
            scrollState !== "about" &&
            scrollState !== "projects"
        ) {
            setScrollState("about");
        } else if (
            scrollPosition > projectsOffset - 200 &&
            scrollState !== "projects" &&
            scrollState !== "home"
        ) {
            setScrollState("projects");
        }
    };


    useEffect(() => {
        const vh = window.innerHeight * 0.08;

        if (scrollState === "home") {
            homeRef.current.scrollIntoView({ behavior: "smooth", top: homeRef - vh, });
            const CurrentScrollLocation = homeRef.current.scrollTop;
            homeRef.current.scrollTo({ top: CurrentScrollLocation - vh })

        } else if (scrollState === "about") {
            aboutRef.current.scrollIntoView({ behavior: "smooth" });
        } else if (scrollState === "projects") {
            projectsRef.current.scrollIntoView({ behavior: "smooth" });
        }

        window.addEventListener("scroll", handleScroll);

        return () => {
            window.addEventListener("scroll", handleScroll);
        }

    }, [scrollState])

    return (
        <div className="App">
            <Header navClick={handleNavScroll} active={scrollState} />
            <main>
                <Home homeRef={homeRef} aboutRef={aboutRef} projectsRef={projectsRef} />
                <About homeRef={homeRef} aboutRef={aboutRef} projectsRef={projectsRef} />
                <Projects homeRef={homeRef} aboutRef={aboutRef} projectsRef={projectsRef} />
            </main>
        </div>
    );
}

export default App;

Header.jsx

import React from 'react'
import "./Header.scss"

function Header({ navClick, active }) {

    return (
        <header>
            <ul className='navbar'>
                <li
                    className={active === "home" ? "navitem active" : "navitem"}
                    onClick={() => {navClick("home")}}>ZBIRKE PJESAMA</li>
                <li
                    className={active === "about" ? "navitem active" : "navitem"}
                    onClick={() => {navClick("about")}}>O MENI</li>
                <li
                    className={active === "projects" ? "navitem active" : "navitem"}
                    onClick={() => {navClick("projects")}}>PROJEKTI</li>
            </ul>
        </header>
    )
}

export default Header

I tried doing it using the isNavigating state but failed and I got messed up in my head and could not find the way to properly update isNavigating state and either run onClick or Scroll depending on the state.

0 Answers0