📝

【React】子->親->子のデータ更新をしたい

2023/02/05に公開

背景

前回の記事に引き続き、三本線を押したらメニューが表示されるように調査していました。
https://zenn.dev/milkandhoney995/articles/7c8f65d7065526

フォルダ構成

treeコマンドは便利だああ

$ tree .
components
└── layouts
    ├── header
    │   ├── header.module.scss
    │   └── header.tsx
    ├── layout.tsx
    └── navigation
        ├── navigation.module.scss
        └── navigation.tsx

対応

今回は、三本線がクリックに対応してメニュー表示を切り替えたいので、

  1. header.tsxがlayout.tsxに、三本線がクリックされたことを伝える
  2. layout.tsxがその情報を受け取る
  3. layout.tsxがnavigation.tsxに2の情報を伝える

という手順で対応しました。

1. header.tsxがlayout.tsxに、三本線がクリックされたことを伝える

前回の記事で、useStateを使いメニューの開閉状態を維持するnavOpenを作りました。
このnavOpenを、props.setMenuOpen(navOpen)で親のlayout.tsxに渡します。

import { useState } from "react";

export default function Header(props) {
  const [navOpen, setNavOpen] = useState(false);
  const toggleNav = () => {
    setNavOpen(!navOpen);
  };
  props.setMenuOpen(navOpen)

2. layout.tsxがその情報を受け取る

次に、親のlayout.tsxでnavOpenの状態を受け取ります。
ここで、navOpenの状態は、menuOpenに

import Header from "./header/header";
import Navigation from "./navigation/navigation";
import { useState } from "react";

export default function Layout() {
  const [menuOpen, setMenuOpen] = useState(false);
  return(
    <>
      <Navigation></Navigation>
      <Header setMenuOpen={setMenuOpen}></Header>
    </>
  )
}

3. layout.tsxがnavigation.tsxに2の情報を伝える

navOpenの状態はmenuOpenに代入されるので、これをnavigation.tsxに渡します。

layout.tsx

export default function Layout() {
  const [menuOpen, setMenuOpen] = useState(false);
  return(
    <>
      <Navigation setShowMenu={menuOpen}></Navigation>
      <Header setMenuOpen={setMenuOpen}></Header>
    </>
  )
}

navigation.tsxでは、props.setShowMenuでmenuOpenの状態を取得します。
これで、props.setShowMenuがtrueのとき、つまり三本線がクリックされた際にメニューを表示するnav__activeNavクラスが適用されるようになりました!!

...(略)...
export default function Navigation(props) {
  return(
    <nav className={`${classes.nav} ${props.setShowMenu ? `${classes.nav__activeNav}` : ""}`}>
      <div className={classes.nav__content}>
        <ul className={classes.nav__menu}>
          ...(略)...
    </nav>
  )
}

ふう〜〜
nav__activeNavっていうクラス名変えられないかなあ...とか細かい点はひとまず置いとくとして、ひとまず解決。

Discussion