deepen
deepen

Reputation: 61

How to pass states between function components in React

My Navbar component has 2 child components. Every components has his own state. States working ok within their components. How to update both states from false to true on same time when both function onClick will be executed?

Main component Navbar

import Hamburger from "./Hamburger";
import ListMenu from "./ListMenu";

const Navbar = () => {
  return (
    <div className="navContainer">
      <nav className="navigation">
        <div className="logo">LOGO</div>
        <ListMenu />
        <Hamburger />
      </nav>
    </div>
  );
};

ListMenu component

import React, { useState } from "react";

const ListMenu = () => {
  const [showMobileMenu, setShowMobileMenu] = useState(false);

  const menu = ["HOME", "PRODUCTS", "ABOUT", "CONTACT"];

  const onClick = () => {
    if (window.innerWidth < 757) {
      setShowMobileMenu(!showMobileMenu);
    }
  };
  return (
  <ul className={`navList ${showMobileMenu ? "open" : ""}`}>
     {menu.map((item) => (
       <li key={item} className="listItem" onClick={onClick}>
         {item}
       </li>
     ))}
   </ul>
  );
};

export default ListMenu;

Hamburger component

import React, { useState } from "react";

const Hamburger = () => {
  const [navBarStatus, setNavBarStatus] = useState(false);

  const onClick = () => {
    if (window.innerWidth < 757) {
      setNavBarStatus(!navBarStatus);
    }
  };

  return (
    <div className="nav_bar">
      <div
        onClick={onClick}
        className={`hamburger ${navBarStatus ? "is-active" : ""}`}
      >
        <span className="line"></span>
        <span className="line"></span>
        <span className="line"></span>
      </div>
    </div>
  );
};

export default Hamburger;

Upvotes: 1

Views: 405

Answers (1)

MB_
MB_

Reputation: 1747

Move all the states from children components to the parent component and pass them in props.

Navbar.js

import React, { useState } from "react";

import Hamburger from "./Hamburger";
import ListMenu from "./ListMenu";

const Navbar = () => {
  const [showMobileMenu, setShowMobileMenu] = useState(false);    // here
  const [navBarStatus, setNavBarStatus] = useState(false);        // here

  return (
    <div className="navContainer">
      <nav className="navigation">
        <div className="logo">LOGO</div>
        <ListMenu
          showMobileMenu={showMobileMenu}                        // props
          setShowMobileMenu={setShowMobileMenu}                  // props
        />
        <Hamburger
          navBarStatus={navBarStatus}                            // props
          setNavBarStatus={setNavBarStatus}                      // props
        />
      </nav>
    </div>
  );
};

export default Navbar;

ListMenu.js

import React from "react";

// See props below showMobileMenu and setShowMobileMenu
const ListMenu = ({ showMobileMenu, setShowMobileMenu }) => { 
  const menu = ["HOME", "PRODUCTS", "ABOUT", "CONTACT"];

  const onClick = () => {
    if (window.innerWidth < 757) {
      setShowMobileMenu(!showMobileMenu);
    }
  };
  return (
    <ul className={`navList ${showMobileMenu ? "open" : ""}`}>
      {menu.map(item => (
        <li key={item} className="listItem" onClick={onClick}>
          {item}
        </li>
      ))}
    </ul>
  );
};

export default ListMenu;

Hamburger.js

import React from "react";

// See props below navBarStatus and setNavBarStatus
const Hamburger = ({ navBarStatus, setNavBarStatus }) => {
  const onClick = () => {
    if (window.innerWidth < 757) {
      setNavBarStatus(!navBarStatus);
    }
  };

  return (
    <div className="nav_bar">
      <div
        onClick={onClick}
        className={`hamburger ${navBarStatus ? "is-active" : ""}`}
      >
        <span className="line" />
        <span className="line" />
        <span className="line" />
      </div>
    </div>
  );
};

export default Hamburger;

Demo : Stackblitz

Upvotes: 3

Related Questions