📝
【React】子->親->子のデータ更新をしたい
背景
前回の記事に引き続き、三本線を押したらメニューが表示されるように調査していました。
フォルダ構成
treeコマンドは便利だああ
$ tree .
components
└── layouts
├── header
│ ├── header.module.scss
│ └── header.tsx
├── layout.tsx
└── navigation
├── navigation.module.scss
└── navigation.tsx
対応
今回は、三本線がクリックに対応してメニュー表示を切り替えたいので、
- header.tsxがlayout.tsxに、三本線がクリックされたことを伝える
- layout.tsxがその情報を受け取る
- 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
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