Next.js Discord

Discord Forum

user side rendering

Unanswered
Cape lion posted this in #help-forum
Open in Discord
Cape lionOP
Hello everyone I have a technical issue about state shared between 2 files

I have a menu button to close/open my nav bar in mobile screen. I want add/removed a class in function of the state open/close of my nav bar to hidde or make it visible.
My menu button is a component in an external jsx file that I put as "user side rendering" imported and use in my Layout.

My navbar is used in my layout file but the layout is a server component by default. I was thinking to may be: - set my layout file too as client rendered component.
- put in Layout component the useState and share the state in props in my button component

but as I have meta data in my Layout Next doesn't allow me to put as use client the file:

You are attempting to export "metadata" from a component marked with "use client", which is disallowed. Either remove the export, or the "use client" directive. Read more: https://nextjs.org/

so I don't really know what to do.

Do you have a better idea ?

My code below:

the Layout file:
"use client"
import Link from "next/link"
import NavButton from "../components/NavButton";

export const metadata = {
  title: 'Fresnay Thibaud DEV',
  description: 'Welcome to my website',
}

export default function RootLayout({ children }) {
  let [clickNav, setClickNav] = useState(false);
  return (
    <html lang="en">
      <body className={roboto.className}>
        <header>
          <Link href="/">
            <Image
              src={TFPic}
              alt="Logo TF"
            ></Image>
          </Link>
    
          <nav className={`horizonNav ${isNavOpen === false ? "navNotOpen" : "navOpen"}`}>
            <ul>
              <li><Link href="/">Home</Link></li>
              <li><Link href="/portfolio">My Projects</Link></li>
              <li><Link href="/experiences">Experiences</Link></li>
              <li><Link href="/aboutMe">About me</Link></li>
            </ul>
          </nav>

         {...}

10 Replies

Cape lionOP
and below my button component file:

"use client";
import { useState } from "react";

const NavButton = (props) => {
    const clickedOrNot = () => {
        setClickNav(!props.clickNav);
    }

    
    return <div className="navButton" onClick={clickedOrNot}>
                { clickNav === false ?
                    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368">
                        <path d="M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z"/>
                    </svg>
                    :
                    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368">
                        <path d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z"/>
                    </svg>
                }
            </div>
// first svg is a menu Icon and second svg is a cross
}

export default NavButton;
Cape lionOP
I had an idea its to create a parent component named NavBar with 2 child Nav and NavButton
all 3 are "use client" as client rendered components. I pass the state clickNav from
jslet [clickNav, setClickNav] = useState(false);
as props in <Nav /> and <NavButton /> and setClickNav as props too at NavButton to change the state when the menu icon is clicked... But it's not working
American Chinchilla
Sorry i dont fully understand your question
If its state share between two files you can either
1) lift up the state
2) use context
3) prop drilling
If the menu button isnt related to seo , then it better to just import it where the navbar open and closed is and make it a client comp. thats how most navbar are.
@American Chinchilla If its state share between two files you can either 1) lift up the state 2) use context 3) prop drilling
Cape lionOP
in fact I created a parent named Navbar to put the state at this level and share the state to NaveButton and Nav. the NavButton when toggled switch the navBar state opening or closing the navbar
my issue was that I couldn't use "use client" in layout.js because layout.js have metadata in and next doesn't allow me to process like that. It's not allowed so I created Navbar to be the parent sharing the state with NavButton and Nav as children. Like this Navbar, NavButton and Nav are client components. But now the problem is that my usestate declaration is in navbar but I need to use the set state in the NavButton component... So I tried to pass the set state as props to the NavButton but it's not working
Cape lionOP
It's Okay I found the solution. I fink I was too much thinking the solution was really simple
"use client"
import { useState } from "react";
import Link from "next/link";


const NavBar = () => {
    const [clickNavBar, setClickNavBar] = useState(false);
    const openCloseNav = () => {
        setClickNavBar(!clickNavBar)
    }
    return <>
        <nav className={`horizonNav ${clickNavBar === false ? "navNotOpen" : "navOpen"}`}>
            <ul>
                <li><Link href="/">Home</Link></li>
                <li><Link href="/portfolio">My Projects</Link></li>
                <li><Link href="/experiences">Experiences</Link></li>
                <li><Link href="/aboutMe">About me</Link></li>
            </ul>
        </nav>
        <div className="navButton" onClick={openCloseNav}>
            {clickNavBar === false ?
                <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368">
                    <path d="M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z" />
                </svg>
                :
                <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368">
                    <path d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z" />
                </svg>
            }
        </div>
    </>


}

export default NavBar
all in one
in Navbar.js no other components