1. 概要
前回はHooksのuseState(値を共有)の使い方についてでした。今回はHooksのuseContextを使いコンポネント間で値を共有する内容となります。
対象としては開発を1年程やってて自分で最初から開発してみたい方になります。そのため細かい用語などの説明はしません。
2. nodeのインストール
こちらを参考
3. プロジェクトを作成
こちらを参考
4. 必要なライブラリをインストール
こちらを参考
5. ソースコード
※前回より差分のみを記載
5-1-1. src/app/hooks/hook03/page.module.scss
.component {
color: blue;
& ul {
margin-left: 20px;
& li {
list-style: disc;
}
}
}
5-1-2. src/app/hooks/hook03/counter-provider.tsx
import { useState, createContext, Context, useContext } from "react";
const CounterWatchContext: Context<number> = createContext(0);
const CounterUpdateContext: Context<any> = createContext(0);
export const CounterProvider = ({ children }: any) => {
const [count, setCount] = useState(0);
return (
<CounterWatchContext.Provider value={count}>
<CounterUpdateContext.Provider value={setCount}>
{children}
</CounterUpdateContext.Provider>
</CounterWatchContext.Provider>
);
};
export const useWatchCounter = () => useContext(CounterWatchContext);
export const useUpdateCounter = () => useContext(CounterUpdateContext);
5-1-3. src/app/hooks/hook03/grandchild.tsx
import Box from "@mui/material/Box";
import { useWatchCounter } from "./counter-provider";
const Grandchild = () => {
const count = useWatchCounter();
return (
<>
<Box
sx={{
width: "100%",
p: 2,
border: "1px dashed grey",
borderRadius: "20px",
backgroundColor: "cyan",
"&:hover": {
backgroundColor: "white",
opacity: [0.9, 0.8, 0.7],
},
}}
>
Grandchild({count})
</Box>
</>
);
};
export default Grandchild;
5-1-4. src/app/hooks/hook03/child.tsx
import Box from "@mui/material/Box";
import Grandchild from "./grandchild";
import { useWatchCounter } from "./counter-provider";
const Child = () => {
const count = useWatchCounter();
return (
<>
<Box
sx={{
width: "100%",
p: 2,
border: "1px dashed grey",
borderRadius: "20px",
backgroundColor: "yellow",
"&:hover": {
backgroundColor: "white",
opacity: [0.9, 0.8, 0.7],
},
}}
>
Child({count})
<Grandchild />
</Box>
</>
);
};
export default Child;
5-1-5. src/app/hooks/hook03/myself.tsx
import { Button } from "@mui/material";
import Box from "@mui/material/Box";
import scss from "./page.module.scss";
import GoBack from "@/lib/components/go-back";
import { useWatchCounter, useUpdateCounter } from "./counter-provider";
import Child from "./child";
const Myself = () => {
const count = useWatchCounter();
const setCount = useUpdateCounter();
const countUp = () => setCount((prev: number) => ++prev);
return (
<div className={scss.component}>
<GoBack />
<br />
<br />
<ul>
<li>Updating the screen</li>
<ul>
<li>Sharing data between components</li>
</ul>
</ul>
<br />
<Box
sx={{
width: "100%",
p: 2,
border: "1px dashed grey",
borderRadius: "20px",
backgroundColor: "orange",
"&:hover": {
backgroundColor: "white",
opacity: [0.9, 0.8, 0.7],
},
}}
>
Myself({count})
<Child />
</Box>
<br />
<ul>
<li>Check the sharing data (Click below button)</li>
</ul>
<br />
<Button
variant="contained"
size="medium"
color="primary"
onClick={() => countUp()}
>
Clicked {count} times.
</Button>
</div>
);
};
export default Myself;
5-1-6. src/app/hooks/hook03/page.tsx
"use client";
import { CounterProvider } from "./counter-provider";
import Myself from "./myself";
const Hook03 = () => {
return (
<CounterProvider>
<Myself />
</CounterProvider>
);
};
export default Hook03;
5-1-7. src/app/hooks/page.tsx
"use client";
import React from "react";
import { Link } from "@mui/material";
import scss from "./page.module.scss";
const Hooks = () => {
return (
<div className={scss.components}>
<ul>
<li>
<Link href="/hooks/hook01" underline="hover">
Hook01
</Link>
</li>
<li>
<Link href="/hooks/hook02" underline="hover">
Hook02
</Link>
</li>
<li>
<Link href="/hooks/hook03" underline="hover">
Hook03
</Link>
</li>
</ul>
</div>
);
};
export default Hooks;
6. サーバーを起動
npm run dev
7. ブラウザで確認
- http://localhost:3000

8. ディレクトリの構造
.
├── README.md
├── next-env.d.ts
├── next.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ ├── next.svg
│ └── vercel.svg
├── src
│ ├── app
│ │ ├── components
│ │ │ ├── component01
│ │ │ │ ├── page.module.scss
│ │ │ │ └── page.tsx
│ │ │ ├── component02
│ │ │ │ ├── page.module.scss
│ │ │ │ └── page.tsx
│ │ │ ├── component03
│ │ │ │ ├── page.module.scss
│ │ │ │ └── page.tsx
│ │ │ ├── page.module.scss
│ │ │ └── page.tsx
│ │ ├── events
│ │ │ ├── event01
│ │ │ │ ├── page.module.scss
│ │ │ │ └── page.tsx
│ │ │ ├── page.module.scss
│ │ │ └── page.tsx
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── globals.scss
│ │ ├── hooks
│ │ │ ├── hook01
│ │ │ │ ├── page.module.scss
│ │ │ │ └── page.tsx
│ │ │ ├── hook02
│ │ │ │ ├── page.module.scss
│ │ │ │ └── page.tsx
│ │ │ ├── hook03
│ │ │ │ ├── child.tsx
│ │ │ │ ├── counter-provider.tsx
│ │ │ │ ├── grandchild.tsx
│ │ │ │ ├── myself.tsx
│ │ │ │ ├── page.module.scss
│ │ │ │ └── page.tsx
│ │ │ ├── page.module.scss
│ │ │ └── page.tsx
│ │ ├── layout.module.scss
│ │ ├── layout.tsx
│ │ ├── page.module.scss
│ │ └── page.tsx
│ ├── lib
│ │ ├── common
│ │ │ ├── definitions.ts
│ │ │ └── sidebar-links.tsx
│ │ ├── components
│ │ │ ├── alert-snackbar.tsx
│ │ │ ├── go-back.tsx
│ │ │ └── spacer.tsx
│ │ ├── footer.tsx
│ │ ├── header.tsx
│ │ ├── sidebar.tsx
│ │ └── utils
│ │ └── util.ts
│ └── scss
│ └── common
│ ├── _index.scss
│ ├── _mixin.scss
│ ├── _mq.scss
│ └── _variables.scss
├── tailwind.config.ts
└── tsconfig.json
19 directories, 54 files
9. 備考
今回はHooksのuseContextを使いコンポネント間で値を共有する内容でした。
10. 参考
- Docs | Next.js (nextjs.org)
- Quick Start – React
- Material UI: React components based on Material Design (mui.com)
投稿者プロフィール

-
開発好きなシステムエンジニアです。
卓球にハマってます。
最新の投稿
【Next.js】2025年2月9日【NextJS】View and Download PDF
【AWS】2025年2月1日【AWS】Github ActionsやAWS SAMを使ってAWS S3・CloudFrontにウェブコンテンツをデプロイし、サブドメインにアクセスできるようにする
【AWS】2025年1月25日【AWS】Deploy Serverless NextJS app with AWS Lambda Web Adapter using AWS SAM
【Next.js】2025年1月16日【NextJS】Access nextjs app launched on WSL2 from an external terminal