ã¯ããã«
æ¬æ¥ã¯ãã¦ã¼ã¶ã¼ç»é²ããã°ã¤ã³ããã°ã¢ã¦ãã®æ©è½ãæã¤èªè¨¼ã¢ããªã®åºæ¬çãªæ§æãåå¿è åãã«è§£èª¬ãã¾ãã
Reactã§ã¯ãã¦ã¼ã¶ã¼ã®èªè¨¼ç¶æ ã管çããããã«React ContextãReduxãªã©ã®ç¶æ 管çã©ã¤ãã©ãªã使ç¨ããã®ãä¸è¬çã§ãã
åå¿è ã«ã¯ãReactã®ç¶æ 管çããã¡ã¤ã«æ§é ããã¼ã¿ããã¼ã«é¢ããæ¦å¿µãç解ãããã¨ã¯åãã¦ã®èª²é¡ããããã¾ããã
ãã®ãããReact ContextãReduxã®ãããªç¶æ 管çã©ã¤ãã©ãªã使ããã¨ãä¸è¬çã§ããããããã¯åå¿è ã«ã¨ã£ã¦ã¯å°ãè¤éã«æããããããã¾ããã
React Contextããã¯ã使ã£ãç¶æ 管çã§ã¯ãé常ããããã¡ã¤ã«æ§é ãè¤éã«ãªããã¨ãããã¾ãã
ã¾ããReduxã¯å°ç¨ã®ç¶æ 管çã©ã¤ãã©ãªã§ãããããèªä½ãå¦ç¿ããå¿ è¦ãããã¾ãã
ãããã®ã©ã¤ãã©ãªã®ä½¿ç¨ã¯ãåãã¦ã®Reactããã¸ã§ã¯ãã«ã¨ã£ã¦ã¯å¿ é ã§ã¯ããã¾ããã
åå¿è ã®æ¹ã«ã¨ã£ã¦ã¯ãReactã®åºæ¬çãªç¶æ 管çææ³ã§ããStateã¨Propsã使ç¨ãããã¨ã§ãååãªå ´åãããã¾ãã
ãã ããããã¸ã§ã¯ããè¤éåãããã大è¦æ¨¡ãªã¢ããªã±ã¼ã·ã§ã³ãéçºããå ´åã¯ãç¶æ 管çã©ã¤ãã©ãªã®ä½¿ç¨ãæ¤è¨ãããã¨ãéè¦ã§ãã
ãã®éã¯ãReact ContextãReduxã®ããã¥ã¡ã³ãããã¥ã¼ããªã¢ã«ãåèã«ããªãããå°ããã¤å¦ç¿ãé²ããã¨è¯ãã§ãããã
ç¶æ 管çã¯Reactéçºã®éè¦ãªè¦ç´ ã§ãããæåã¯å°ãè¤éã«æããããããã¾ããã
ããããå®éã®ããã¸ã§ã¯ãã§çµé¨ãç©ã¿ãªããå¦ç¿ãã¦ãããã¨ã§ãããæ·±ãç解ã¨ã¹ãã«ã®åä¸ãæå¾ ã§ãã¾ãã
ããã§ããã®è¨äºã§ã¯åå¿è ã®æ¹ã«ãããããããæ¹æ³ã§ãã·ã³ãã«ãªã¦ã¼ã¶ã¼èªè¨¼ã¢ããªãä¾ã«è§£èª¬ãã¦ããã¾ãã
React ContextãReduxã©ã¤ãã©ãªã使ããã«ç¶æ ã管çããæ¹æ³ãç´¹ä»ãã¾ãã
React.jsã使ç¨ãã¦ã·ã³ãã«ãªã¦ã¼ã¶ã¼èªè¨¼ã¢ããªãä½æããããã«ã¯ãããã¤ãã®ã¹ããããå¿ è¦ã§ãã
æ¬æ¥ã®å ·ä½çãªæé ã¨ãã¦ã¯ã以ä¸ã®ãããªæµãã§é²ãã¾ãã
ã¾ããReact Routerã使ç¨ãã¦ã«ã¼ãã£ã³ã°ãè¨å®ãã¾ãã
ã¢ããªã±ã¼ã·ã§ã³ã®è¦ªã³ã³ãã¼ãã³ãï¼Appã³ã³ãã¼ãã³ãï¼ã§BrowserRouterã³ã³ãã¼ãã³ãã使ç¨ããã«ã¼ãã£ã³ã°æ©è½ãæå¹ã«ãã¾ãã
Routesã³ã³ãã¼ãã³ãå ã«åã ã®ã«ã¼ãï¼Routeï¼ãå®ç¾©ããåRouteã³ã³ãã¼ãã³ãã«ã¯pathå±æ§ã¨elementå±æ§ãæå®ãã¾ããpathå±æ§ã¯è¡¨ç¤ºãããã¹ãæå®ããelementå±æ§ã«ã¯ãã®ãã¹ã«å¯¾å¿ããã³ã³ãã¼ãã³ããæå®ãã¾ãã
次ã«ãã¡ãã¥ã¼ããã²ã¼ã·ã§ã³ãä½æãã¾ãã
navè¦ç´ å ã«ãªã³ã¯ãé ç½®ããã«ã¼ãã£ã³ã°ãããåãã¼ã¸ã¸ã®ããã²ã¼ã·ã§ã³ãæä¾ãã¾ããLinkã³ã³ãã¼ãã³ãã使ç¨ãã¦åãã¼ã¸ã¸ã®ãªã³ã¯ãä½æãã¾ãã
åãã¼ã¸ã®ã³ã³ãã¼ãã³ãã¨ãã¦ãHomeãLoginãRegisterãDashboardã³ã³ãã¼ãã³ããä½æãã¾ããããããã®ã³ã³ãã¼ãã³ãã¯ã対å¿ããã«ã¼ãã®elementå±æ§ã«æå®ãããã¨ãã«è¡¨ç¤ºããã¾ãã
ã¾ãããã¼ãã®è¨å®ãè¡ãã¾ãã
useStateããã¯ã使ç¨ãã¦ãã¼ãã管çããããããã®ã¹ãã¼ãå¤æ°ã«åºã¥ãã¯ã©ã¹ã親è¦ç´ ã«è¿½å ãããã¨ã§CSSã¹ã¿ã¤ã«ãé©ç¨ãã¾ãã
å ·ä½çãªåã³ã³ãã¼ãã³ãã®æé ã¨ãã¦ã¯ãã¾ãæ°è¦ç»é²ï¼Registerï¼ã§ãã
ã¦ã¼ã¶ã¼ããã©ã¼ã ã«å ¥åããæ å ±ï¼emailãpasswordãnicknameï¼ãåå¾ããfetchDataé¢æ°ã使ç¨ãã¦APIã¨ã³ããã¤ã³ãã«å¯¾ãã¦POSTãªã¯ã¨ã¹ããéä¿¡ããã¦ã¼ã¶ã¼æ å ±ãç»é²ãã¾ãã
ç»é²ãæåããå ´åããã¼ã¯ã³ï¼nicknameï¼ããã¼ã«ã«ã¹ãã¬ã¼ã¸ã«ä¿åãã¾ããæ°è¦ç»é²ãã¿ã³ãã¯ãªãã¯ãããæã«ãã®é¢æ°ãå¼ã³åºããç»é²å¦çãè¡ãã¾ããç»é²å¾ã¯ãã°ã¤ã³ãã¼ã¸ã«ãªãã¤ã¬ã¯ãããã¾ãã
次ã«ãã°ã¤ã³ï¼Loginï¼ã§ãã
ã¦ã¼ã¶ã¼ããã©ã¼ã ã«å ¥åããã¡ã¼ã«ã¢ãã¬ã¹ã¨ãã¹ã¯ã¼ããåå¾ãã¾ãã
å ¥åãããæ å ±ãæå¹ãªå ´åããã¼ã¯ã³ï¼ä¾: "example_token"ï¼ããã¼ã«ã«ã¹ãã¬ã¼ã¸ã«ä¿åãã¾ããLoginé¢æ°ã¯ããã°ã¤ã³ãã¿ã³ãã¯ãªãã¯ãããæã«å®è¡ãããå ¥åãããæ å ±ã®æ¤è¨¼ã¨ãã¼ã¯ã³ã®ä¿åãè¡ãã¾ãã
ãã°ã¤ã³æåå¾ãããã·ã¥ãã¼ããã¼ã¸ã«ãªãã¤ã¬ã¯ãããã¾ãã
æå¾ã«ããã·ã¥ãã¼ãï¼Dashboardï¼ã§ãã
ã¾ããlocalStorage.getItem('token') ã使ç¨ãã¦ãã¼ã¯ã³ã®æç¡ã確èªãã¾ãã
ãã¼ã¯ã³ãåå¨ããå ´åããã¼ã¯ã³ã«é¢é£ä»ããããããã¯ãã¼ã ã表示ãã¾ãã
ã¾ããLogouté¢æ°ã¯ãã°ã¢ã¦ããã¿ã³ãã¯ãªãã¯ãããæã«å®è¡ããããã¼ã¯ã³ã¨ããã¯ãã¼ã ããã¼ã«ã«ã¹ãã¬ã¼ã¸ããåé¤ãã¾ãã
ãã°ã¢ã¦ãå¾ã¯ãã°ã¤ã³ãã¼ã¸ã«ãªãã¤ã¬ã¯ãããã¾ãã
ãããã®æé ã«ãã£ã¦ãReactã®ç¶æ 管çãã·ã³ãã«ã«å®è£ ããã¦ã¼ã¶ã¼ã®èªè¨¼ç¶æ ã管çãããã¨ãã§ãã¾ãã
React ContextãReduxã使ç¨ããªãå ´åã§ãããã®ãããªåºæ¬çãªææ³ã§ã¦ã¼ã¶ã¼ã®èªè¨¼ç¶æ ã管çãããã¨ãã§ãã¾ãã
以ä¸ã®ãããªå®è£ ã«ãªãã¾ãã
ããã¸ã§ã¯ãä½æ
ã¾ããCRAï¼Create-React-Appï¼ã§Reactã¢ããªã±ã¼ã·ã§ã³ãä½æããå¿ è¦ãªããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ãã¾ãã
ããã§ã¯ãReact Router v6ã使ç¨ããããã«ãreact-router-domããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ãã¾ãã
npx create-react-app auth-app cd auth-app npm install react-router-dom
React Routerã使ç¨ãã¦ãã¦ã¼ã¶ã¼ç»é²ããã°ã¤ã³ããã°ã¢ã¦ããªã©ã®åæ©è½ã«å¯¾å¿ããã«ã¼ããè¨å®ã§ãã¾ãã
ããã«ãããç°ãªãç»é¢ãæ©è½ã«ã¦ã¼ã¶ã¼ãããã²ã¼ããããã¨ãã§ãã¾ãã
React Routerã使ç¨ãããã¼ã¸é·ç§»ãè¡ãå ´åãããã¯SPAï¼Single-Page Applicationï¼ã¢ããªã±ã¼ã·ã§ã³ã¨è¦ãªããã¨ãã§ãã¾ãã
次ã«ãã¢ããªã±ã¼ã·ã§ã³ã®ãã£ã¬ã¯ããªæ§é ãè¨å®ãã¾ãã
ä¸è¬çãªæ§é ã¨ãã¦ä»¥ä¸ã®ããã«ãã¾ãã
src âââ components â âââ Home.js â âââ Login.js â âââ Register.js â âââ Dashboard.js âââ App.js âââ index.js âââ App.css âââ index.module.css
Home.jsã¯èªè¨¼åã®ãã¼ã ãã¼ã¸ã表示ããLogin.jsã¯ãã°ã¤ã³ç»é¢ãRegister.jsã¯æ°è¦ã¦ã¼ã¶ã¼ç»é²ç»é¢ãDashboard.jsã¯èªè¨¼å¾ã®ããã·ã¥ãã¼ãç»é¢ã表ãã¾ãã
çè¨æç¹ã§ã®Reactããã³React Routerã®ãã¼ã¸ã§ã³ã¯ä»¥ä¸ã§ãã
// package.json "dependencies": { "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.14.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" },
ã¹ã¿ã¤ãªã³ã°
ã¾ãã軽ãã¹ã¿ã¤ãªã³ã°ã®å¤æ´ãå ãã¾ãããã
以ä¸ã¯ãApp.cssãã¡ã¤ã«ã®ä¿®æ£å 容ã§ãã
body { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } .app { display: flex; flex-direction: column; align-items: center; min-height: 100vh; /* å ±éã®ã¹ã¿ã¤ã« */ } .app.light { background-color: #f1f1f1; /* ã©ã¤ããã¼ãã®ã¹ã¿ã¤ã« */ } .app.dark { background-color: #333; color: #fff; /* ãã¼ã¯ãã¼ãã®ã¹ã¿ã¤ã« */ } nav { display: flex; justify-content: center; align-items: center; width: 100%; padding: 20px; background-color: #f1f1f1; } nav ul { display: flex; justify-content: center; align-items: center; list-style: none; padding: 0; } nav li { margin-right: 10px; } nav li:last-child { margin-right: 0; }
ããã«ãããCSS Modulesã使ç¨ãã¦ã¹ã¿ã¤ã«ãã¤ã³ãã¼ãããåºæã®ã¹ã¿ã¤ã«ã¯ã©ã¹ãçæããã¾ããçæãããã¯ã©ã¹ã¯ãåã³ã³ãã¼ãã³ãã®è¦ç´ ã«é©ç¨ããã¾ãã
次ã«ãindex.cssãã¡ã¤ã«ã®ååãindex.module.cssã«å¤æ´ãã¾ãã
nav { margin-bottom: 20px; } .box { border: 1px solid #ccc; padding: 20px; border-radius: 4px; width: 300px; margin: 0 auto; background-color: #f1f1f1; color: #333; } button { background-color: #4f46e5; font-weight: bold; border-radius: 9999px; padding: 1rem 2rem; color: #fff; margin-left: auto; display: flex; align-self: flex-end; }
index.jsãã¡ã¤ã«ã«ç§»åããã¤ã³ãã¼ãã®ãã¹ãæ£ããå¤æ´ãã¾ãããã
// index.js import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.module.css'; //å¤æ´ import App from './App'; import reportWebVitals from './reportWebVitals'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();
CSSã®ã¹ã¿ã¤ãªã³ã°ã¯ãåå¥ã«ã«ã¹ã¿ãã¤ãºãã¦ããã ãã¦ãæ§ãã¾ããã
注æç¹ã¯ãããã¸ã§ã¯ããå°è¦æ¨¡ã§åç´ãªæ§é ãæã¤å ´åãCSSãã¡ã¤ã«ãç¡çã«åããå¿ è¦ã¯ããã¾ããã
ãã ãã³ã³ãã¼ãã³ããã¨ã«CSSãã¡ã¤ã«ãåãããã¨ã§ããã©ã¦ã¶ã¯å¿ è¦ãªã¹ã¿ã¤ã«ã®ã¿ããã¦ã³ãã¼ãããã¬ã³ããªã³ã°ãããã¨ãã§ãã¾ããä¸è¦ãªã¹ã¿ã¤ã«ã®èªã¿è¾¼ã¿ãé¿ãããã¨ã§ãããã©ã¼ãã³ã¹ã®åä¸ãæå¾ ã§ãã¾ãã
ã¾ããåå²ãããCSSãã¡ã¤ã«ã¯ãä»ã®ã³ã³ãã¼ãã³ããã¢ã¸ã¥ã¼ã«ã§åå©ç¨ãããã¨ãã§ãã¾ããå ±éã®ã¹ã¿ã¤ã«ãå¥ã®ãã¡ã¤ã«ã«ã¾ã¨ãããã¨ã§ãéè¤ãé¿ããå¹ççãªã¹ã¿ã¤ã«ã®å ±æãå¯è½ã«ãªãã¾ãã
ããã¦ãå¤æ´ãä¿®æ£ãå¿ è¦ãªå ´åã該å½ããCSSãã¡ã¤ã«ãæ¢ãããããªãã¾ããã¤ã¾ãå¯èªæ§ã¨ä¿å®æ§ã®åä¸ã«ç¹ããã¾ãã
CSSãã¡ã¤ã«ãåãããã©ããã¯ãå®éã¯ããã¸ã§ã¯ãã®è¦ä»¶ãéçºãã¼ã ã®å¥½ã¿ã«ãã£ã¦ç°ãªãã¾ããããã¸ã§ã¯ãã®è¦æ¨¡ãè¤éããä¿å®æ§ãããã©ã¼ãã³ã¹ã®è¦æ±ã«å¿ãã¦ãé©åãªã¢ããã¼ããé¸æãã¦ããããã«ãã¦ãã ããã
親ã³ã³ãã¼ãã³ã
æ¢åã®App.jsã以ä¸ã®ããã«ãã¾ãã
import './App.css'; import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'; import Home from './components/Home'; import Login from './components/Login'; import Register from './components/Register'; import Dashboard from './components/Dashboard'; import { useState } from 'react'; function App() { const [theme] = useState('dark'); // ä¾ã¨ãã¦ãã¼ããè¨å® return ( <Router> <div className={`app ${theme}`}> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/login">Login</Link> </li> <li> <Link to="/register">Register</Link> </li> <li> <Link to="/dashboard">Dashboard</Link> </li> </ul> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/login" element={<Login />} /> <Route path="/register" element={<Register />} /> <Route path="/dashboard" element={<Dashboard />} /> </Routes> </div> </Router> ); } export default App;
Appã³ã³ãã¼ãã³ãã¯ã«ã¼ãã³ã³ãã¼ãã³ãã§ãã
ã«ã¼ãã³ã³ãã¼ãã³ãã¯ãReactã¢ããªã±ã¼ã·ã§ã³ã®ã¨ã³ããªã¼ãã¤ã³ãã§ãããä»ã®ã³ã³ãã¼ãã³ããå«ããã«ã¼ãã£ã³ã°ãå ±éã®ç¶æ 管çãªã©ã®ã¢ããªã±ã¼ã·ã§ã³ã®ãããã¬ãã«ã®è¨å®ãè¡ãã¾ãã
App ã³ã³ãã¼ãã³ãå
ã®<Router>
ã³ã³ãã¼ãã³ãã¯ãReact Routerããã±ã¼ã¸ã使ç¨ãã¦ã«ã¼ãã£ã³ã°ãè¨å®ããããã«å¿
è¦ã§ãã
<nav>
è¦ç´ å
ã®<Link>
ã³ã³ãã¼ãã³ãã¯ãã¢ããªã±ã¼ã·ã§ã³ã®ããã²ã¼ã·ã§ã³ã¡ãã¥ã¼ãæä¾ããããã®ãªã³ã¯ã表示ãã¾ãã
<Routes>
ã³ã³ãã¼ãã³ãã§ã¯ã<Route>
ã³ã³ãã¼ãã³ããå«ããããã®ã³ã³ããã§ãããå<Route>
ã³ã³ãã¼ãã³ãã¯ãç¹å®ã®ãã¹ã«ãããããå ´åã«è¡¨ç¤ºãããã³ã³ãã¼ãã³ããå®ç¾©ãã¾ãã
ãããã£ã¦ãAppã³ã³ãã¼ãã³ãã¯ã¢ããªã±ã¼ã·ã§ã³ã®ã«ã¼ãã³ã³ãã¼ãã³ãã§ãããä»ã®ã³ã³ãã¼ãã³ããå«ãã ãã«ã¼ãã£ã³ã°ã®è¨å®ãè¡ãã¾ãã
ããã«ãããåãã¹ã«å¯¾å¿ããã³ã³ãã¼ãã³ããé©åã«è¡¨ç¤ºããã¾ãã
次ã«ãåã³ã³ãã¼ãã³ããå®è£ ãã¦ããã¾ãã
åã³ã³ãã¼ãã³ãã®å®è£
src
ãã©ã«ãç´ä¸ã«æ°ããcomponents
ãã©ã«ããä½æããã®ä¸ã«åã³ã³ãã¼ãã³ããã¡ã¤ã«ãæ ¼ç´ãã¦ããã¾ãã
// components/Home.js const Home = () => { return ( <div><h1>Home</h1></div> ) } export default Home;
ä¸è¨ã®ãHomeã³ã³ãã¼ãã³ãã¯ãã¢ããªã±ã¼ã·ã§ã³ã®ãã¼ã ãã¼ã¸ã¾ãã¯ãããã¬ãã«ã®ã³ã³ãã³ãã表示ããããã®ã³ã³ãã¼ãã³ãã§ãã
é常ãã¢ããªã±ã¼ã·ã§ã³ã®åæ表示ãã«ã¼ããã¹ ï¼ / ï¼ã«å¯¾å¿ãããã¼ã¸ã¨ãã¦ä½¿ç¨ããã¾ãã
Homeã³ã³ãã¼ãã³ãã¯åç´ãªè¦åºãè¦ç´ <h1>Home</h1>
ãè¿ãã ãã§ãããå®éã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ããã¼ã ãã¼ã¸ã®ãã¶ã¤ã³ãã³ã³ãã³ããé©åã«ã¬ã³ããªã³ã°ããããã«ãããå¤ãã®ã³ã³ãã³ããã³ã³ãã¼ãã³ãã追å ãããã¨ãä¸è¬çã§ãã
ã¢ããªã±ã¼ã·ã§ã³ã®è¦ä»¶ã«å¿ãã¦ãHomeã³ã³ãã¼ãã³ããé©åã«æ¡å¼µãã¦ãã¼ã ãã¼ã¸ã®è¡¨ç¤ºãæ©è½ãå®è£ ãã¦ãã ããã
ãã°ã¤ã³ç¶æ ã®ä¿æ
// components/Login.js import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import styles from '../index.module.css'; const Login = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const navigate = useNavigate(); const handleLogin = () => { // ãã°ã¤ã³ã®å¦çãå®è£ ãã if (email.trim() !== '' && password.trim() !== '') { // ãã°ã¤ã³æåã®å ´åããã¼ã¯ã³ãä¿åãããªã©ã®å¦çãè¡ã console.log("ãã°ã¤ã³ã«æåãã¾ããã"); // ä¾: ãã¼ã¯ã³ããã¼ã«ã«ã¹ãã¬ã¼ã¸ã«ä¿åãã localStorage.setItem('token', 'example_token'); // ããã·ã¥ãã¼ããã¼ã¸ã«ãªãã¤ã¬ã¯ããã navigate('/dashboard'); } else { // ãã°ã¤ã³å¤±æã®å ´åã®å¦çãè¡ãï¼ä¾: ã¨ã©ã¼ã¡ãã»ã¼ã¸ã®è¡¨ç¤ºï¼ console.log('ãã°ã¤ã³ã«å¤±æãã¾ãã'); } }; return ( <div className={styles['box']}> <h2>Login</h2> <form> <input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button type="button" onClick={handleLogin}> Login </button> </form> </div> ); } export default Login;
ä¸è¨ã®ã³ã¼ãã§ã¯ãuseStateããã¯ã使ã£ã¦ãemailã¨passwordã®ç¶æ ã管çãã¦ãã¾ãããããã®ç¶æ ã¯å ¥åãã£ã¼ã«ãã®å¤ã¨ãã¤ã³ãããã¾ãã
useNavigateããã¯ã使ã£ã¦ãReact Routerã®navigateé¢æ°ãåå¾ãã¾ããããã«ããããã°ã¤ã³æåå¾ã«ããã·ã¥ãã¼ããã¼ã¸ã«ãªãã¤ã¬ã¯ããããã¨ãã§ãã¾ãã
handleLoginé¢æ°ã¯ããã°ã¤ã³ãã¿ã³ãã¯ãªãã¯ãããã¨ãã«å®è¡ããã¾ãã
å ¥åãããã¡ã¼ã«ã¢ãã¬ã¹ã¨ãã¹ã¯ã¼ãã空ã§ãªãå ´åã«ããã°ã¤ã³æåã¨ã¿ãªãããã¼ã¯ã³ããã¼ã«ã«ã¹ãã¬ã¼ã¸ã«ä¿åããããã·ã¥ãã¼ããã¼ã¸ã«ãªãã¤ã¬ã¯ããã¾ãã
空ã®å ´åã¯ãã°ã¤ã³å¤±æã¨ã¿ãªãããã¨ã©ã¼ã¡ãã»ã¼ã¸ã表示ããã¾ãã
JSXå
ã§ã¯ã<input>
è¦ç´ ã使ã£ã¦ã¡ã¼ã«ã¢ãã¬ã¹ã¨ãã¹ã¯ã¼ãã®å
¥åãã£ã¼ã«ãã表示ããonChangeã¤ãã³ããã³ãã©ã使ã£ã¦å
¥åå¤ãæ´æ°ãã¾ãã
ãã°ã¤ã³ãã¿ã³ã«ã¯onClickã¤ãã³ããã³ãã©ãè¨å®ããã¯ãªãã¯ãããã¨ãã«handleLoginé¢æ°ãå¼ã³åºããã¾ãã
ãã¼ã«ã«ã¹ãã¬ã¼ã¸ã®ç¢ºèªæ¹æ³ã¯ãGoogle chromeã®ãããããã¼ãã¼ã«ãéããããä¸é¨ã®ã¿ããããApplicationãï¼ã¢ããªã±ã¼ã·ã§ã³ï¼ãé¸æãã¾ãã
å·¦å´ã®ããã²ã¼ã·ã§ã³ããã«ã§ããStorageãï¼ã¹ãã¬ã¼ã¸ï¼ãã¯ãªãã¯ãã¾ãã
ãLocal Storageãï¼ãã¼ã«ã«ã¹ãã¬ã¼ã¸ï¼ãé¸æãã¾ãã
å³å´ã®ããã«ã«ã¯ãç¾å¨ã®ãã¡ã¤ã³ã®ãã¼ã«ã«ã¹ãã¬ã¼ã¸ã«ä¿åããã¦ãããã¼ã¨å¤ã®ä¸è¦§ã表示ããã¾ãã
ããã§ããã¼ã«ã«ã¹ãã¬ã¼ã¸ã«ä¿åããã¦ãããã¼ã¨å¤ã®è©³ç´°ã確èªããããå¿ è¦ã«å¿ãã¦ç·¨éããããããã¨ãã§ãã¾ãã
ããããå®éã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ãããã¯ã¨ã³ãã®èªè¨¼ãµã¼ãã¹ããã¼ã¿ãã¼ã¹ã¨ã®é£æºãå¿ è¦ã§ãããå ¥åãããæ å ±ãæ¤è¨¼ãããªã©ã®å¦çãè¡ãå¿ è¦ãããã¾ãã
ã¾ãããã°ã¤ã³ãæåããå ´åã«ã¯ãã»ãã·ã§ã³ããã¼ã¯ã³ã®ç®¡çæ¹æ³ãé©åã«å®è£ ããå¿ è¦ãããã¾ãã
ãã®ä¾ã§ã¯ãåç´åã®ããã«ãã¼ã«ã«ã¹ãã¬ã¼ã¸ã«ãã¼ã¯ã³ãä¿åãã¦ãã¾ãããå®éã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ã»ãã¥ãªãã£ä¸ã®èæ ®ãå¿ è¦ã§ãã
ãã¼ã«ã«ã¹ãã¬ã¼ã¸ã«é¢ãã詳細ã¯å½è¨äºã®ä»¥ä¸ãåèã«ãã¦ã¿ã¦ãã ããã
ã¦ã¼ã¶ã¼æ å ±ã®ä¿å
以ä¸ã§ã¯ãé¢æ°ã³ã³ãã¼ãã³ãã¨ãã¦å®è£ ããæ°è¦ç»é²æ©è½ãæã¤ã³ã³ãã¼ãã³ãã§ãã
// components/Register.js import { useState, useEffect } from 'react'; import styles from '../index.module.css'; import { useNavigate } from 'react-router-dom'; const Register = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [nickname, setNickname] = useState(''); const navigate = useNavigate(); useEffect(() => { // ãã¦ã³ãæã®å¦çãªã©ãè¨è¿° fetchData(); }, []); const fetchData = async () => { try { const formData = { email, password, nickname // nicknameããã©ã¼ã ãã¼ã¿ã«å«ãã }; const requestOptions = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }; const apiUrl = 'https://jsonplaceholder.typicode.com/users'; const response = await fetch(apiUrl, requestOptions); if (!response.ok) { throw new Error('Registration failed'); } const data = await response.json(); console.log('Registration successful!', data); // ããã§ãã¼ã¯ã³ãä¿åãããªã©ã®å¦çãè¡ã localStorage.setItem('nickname', JSON.stringify(nickname)); // nicknameãæååã¨ãã¦ãã¼ã«ã«ã¹ãã¬ã¼ã¸ã«ä¿å } catch (error) { console.error('Registration failed:', error); // ã¨ã©ã¼ã¡ãã»ã¼ã¸ã表示ãããªã©ã®å¦çãè¡ã } }; const handleRegister = () => { // Registerãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦çãè¨è¿° fetchData(); navigate('/login'); // ç»é²å¾ã«ãã°ã¤ã³ãã¼ã¸ã«ãªãã¤ã¬ã¯ã }; return ( <div className={styles['box']}> <h2>Register(æ°è¦ç»é²)</h2> <form> <input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} /> <input type="text" placeholder="Nickname" value={nickname} onChange={(e) => setNickname(e.target.value)} // nicknameã®å ¥åå¤ãæ´æ°ãã /> <button type="button" onClick={handleRegister}> Register </button> </form> </div> ); } export default Register;
ä¸è¨ã®ã³ã¼ãã§ã¯ãuseStateããã¯ã使ã£ã¦ãemailãpasswordãnicknameã®ç¶æ ã管çãã¦ãã¾ãããããã®ç¶æ ã¯å ¥åãã£ã¼ã«ãã®å¤ã¨ãã¤ã³ãããã¾ãã
useEffectããã¯ã使ã£ã¦ãã³ã³ãã¼ãã³ãããã¦ã³ããããæã«å®è¡ãããå¦çãè¨è¿°ãã¾ããããã§ã¯fetchDataé¢æ°ãå¼ã³åºããã¾ãã
fetchDataé¢æ°ã¯ãç»é²ãã©ã¼ã ã®ãã¼ã¿ãå«ãformDataãªãã¸ã§ã¯ããä½æãããããJSONå½¢å¼ã«å¤æãã¦ãªã¯ã¨ã¹ãã®bodyã«è¨å®ãã¾ãããã®å¾ãfetché¢æ°ã使ã£ã¦APIã«ãªã¯ã¨ã¹ããéä¿¡ããã¬ã¹ãã³ã¹ãåãåãã¾ãã
ã¬ã¹ãã³ã¹ãæ£å¸¸ãªå ´åã¯ããã¼ã¯ã³ã®ä¿åãªã©ã®å¦çãè¡ãã¾ããã¾ããlocalStorage.setItemã使ç¨ãã¦ãnicknameãæååã¨ãã¦ãã¼ã«ã«ã¹ãã¬ã¼ã¸ã«ä¿åãã¾ãã
ç»é²ãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦çã¯handleRegisteré¢æ°ã§è¡ããã¾ããfetchDataé¢æ°ãå¼ã³åºãããç»é²å¾ã«/login
ã¸ã®ãªãã¤ã¬ã¯ããè¡ããã¾ãã
JSXå
ã§ã¯ã<input>
è¦ç´ ã使ã£ã¦ã¡ã¼ã«ã¢ãã¬ã¹ããã¹ã¯ã¼ããããã¯ãã¼ã ã®å
¥åãã£ã¼ã«ãã表示ããonChangeã¤ãã³ããã³ãã©ã使ã£ã¦å
¥åå¤ãæ´æ°ãã¾ãã
ç»é²ãã¿ã³ã«ã¯onClickã¤ãã³ããã³ãã©ãè¨å®ããã¯ãªãã¯ãããã¨ãã«handleRegisteré¢æ°ãå¼ã³åºããã¾ãã
ãã®ã³ã³ãã¼ãã³ãã¯ãæ°è¦ç»é²ãã©ã¼ã ã表示ããã¦ã¼ã¶ã¼ãã¡ã¼ã«ã¢ãã¬ã¹ããã¹ã¯ã¼ããããã¯ãã¼ã ãå ¥åãã¦ç»é²ãããã¨ãã§ãã¾ãã
ç»é²ãæåããã¨ããã¼ã¯ã³ãããã¯ãã¼ã ã®ä¿åãªã©ã®å¦çãè¡ãããã°ã¤ã³ãã¼ã¸ã«ãªãã¤ã¬ã¯ããã¾ãã
ãã ããå®éã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ãç»é²ãã©ã¼ã ã®ãã¼ã¿ãAPIã«éä¿¡ãã¦ã¦ã¼ã¶ã¼ãç»é²ããå¿ è¦ãããã¾ãã
ã¾ãããã¼ã¯ã³ãããã¯ãã¼ã ã®ä¿åæ¹æ³ãã¢ããªã±ã¼ã·ã§ã³ã«å¿ãã¦ã«ã¹ã¿ãã¤ãºããå¿ è¦ãããã¾ãã
ã¨ã©ã¼ã¡ãã»ã¼ã¸ã®è¡¨ç¤ºããã£ã¼ãããã¯ãªã©ã®æ¹åãæ¤è¨ãã¦ãã ããã
ãã°ã¢ã¦ãå¦ç
以ä¸ã¯ãé¢æ°ã³ã³ãã¼ãã³ãã¨ãã¦å®è£ ãããããã·ã¥ãã¼ãæ©è½ãæã¤ã³ã³ãã¼ãã³ãã¨ãªãã¾ãã
// components/Dashboard.js import { useNavigate } from 'react-router-dom'; import styles from '../index.module.css'; const Dashboard = () => { const navigate = useNavigate(); const handleLogout = () => { // ãã¼ã¯ã³ã®åé¤ãã»ãã·ã§ã³ã®ã¯ãªã¢ãªã©ããã°ã¢ã¦ãã«é¢ããå¦çãå®è£ ãã // ä¾: ãã¼ã«ã«ã¹ãã¬ã¼ã¸ãããã¼ã¯ã³ãåé¤ localStorage.removeItem('token'); localStorage.removeItem('nickname'); // ãã°ã¢ã¦ãå¾ã«ãã°ã¤ã³ãã¼ã¸ã«ãªãã¤ã¬ã¯ããã navigate('/login'); console.log("ãã°ã¢ã¦ããã¾ããã") }; return ( <div className={styles['box']}> <h2>Dashboard</h2> {localStorage.getItem('token') && ( <p>Welcome, {localStorage.getItem('nickname')}!</p> )} <button type="button" onClick={handleLogout}> Logout </button> </div> ); } export default Dashboard;
ä¸è¨ã®ã³ã¼ãã¯ãuseNavigateããã¯ã使ã£ã¦ããªãã¤ã¬ã¯ãæ©è½ãå©ç¨ããããã®navigateé¢æ°ãåå¾ãã¾ãã
handleLogouté¢æ°ã¯ããã°ã¢ã¦ããã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦çãå®è£ ãã¦ãã¾ãããã®é¢æ°ã§ã¯ããã¼ã¯ã³ã®åé¤ãã»ãã·ã§ã³ã®ã¯ãªã¢ãªã©ããã°ã¢ã¦ãã«é¢é£ããå¦çãè¡ãã¾ãã
ä¾ã¨ãã¦ãlocalStorage.removeItemã使ç¨ãã¦ããã¼ã«ã«ã¹ãã¬ã¼ã¸ãããã¼ã¯ã³ã¨ããã¯ãã¼ã ãåé¤ãã¦ãã¾ãã
ãã°ã¢ã¦ãå¾ã«ã¯ãnavigateé¢æ°ã使ã£ã¦ãã°ã¤ã³ãã¼ã¸ã«ãªãã¤ã¬ã¯ããã¾ãã'/login'
ã¯ãªãã¤ã¬ã¯ãå
ã®URLã§ãã
JSXå
ã§ã¯ã<p>
è¦ç´ ã使ã£ã¦ããã¼ã¯ã³ãåå¨ããå ´åã«ãWelcome, {nickname}!ãã¨è¡¨ç¤ºãã¾ããããã¯ãã¼ã ã¯ãã¼ã«ã«ã¹ãã¬ã¼ã¸ããåå¾ãã¦è¡¨ç¤ºããã¾ãã
ãã°ã¢ã¦ããã¿ã³ã«ã¯onClickã¤ãã³ããã³ãã©ãè¨å®ããã¦ãããã¯ãªãã¯ãããã¨ãã«handleLogouté¢æ°ãå¼ã³åºããã¾ãã
ãã®ã³ã³ãã¼ãã³ãã¯ãããã·ã¥ãã¼ãã表示ããã¦ã¼ã¶ã¼ã®ãã°ã¤ã³ç¶æ ã«å¿ãã¦è¡¨ç¤ºå 容ãå¶å¾¡ãã¾ãã
ãã¼ã¯ã³ããã¼ã«ã«ã¹ãã¬ã¼ã¸ã«åå¨ããå ´åã¯ãã¦ã¼ã¶ã¼ã®ããã¯ãã¼ã ã¨ãã°ã¢ã¦ããã¿ã³ã表示ããããã°ã¢ã¦ããã¿ã³ãã¯ãªãã¯ãããã¨ããã¼ã¯ã³ã¨ããã¯ãã¼ã ãåé¤ããããã°ã¤ã³ãã¼ã¸ã«ãªãã¤ã¬ã¯ãããã¾ãã
ãã ãããã¡ãã®æ©è½ã®å®è£ ã§ããå®éã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ããã¼ã¯ã³ã®ç®¡çããã°ã¢ã¦ãã«é¢ããå¦çã¯ã¢ããªã±ã¼ã·ã§ã³ã®è¦ä»¶ã«å¿ãã¦ã«ã¹ã¿ãã¤ãºãã¦ããå¿ è¦ãããã¾ãã
ã¾ããããã·ã¥ãã¼ãã®è¡¨ç¤ºå 容ãã¢ããªã±ã¼ã·ã§ã³ã®ãã¶ã¤ã³ãè¦ä»¶ã«åããã¦å¤æ´ãããã¨ãã§ãã¾ãã
注æç¹
åã³ã³ãã¼ãã³ãï¼HomeãLoginãRegisterãDashboardï¼ãæ£ããã¤ã³ãã¼ãããã¦ããã確èªãã¦ãã ããã
å®éã®ãã¡ã¤ã«æ§é ã«åºã¥ãã¦åã³ã³ãã¼ãã³ãã®ãã¹ãæå®ãã¦ã¤ã³ãã¼ãããå¿ è¦ãããã¾ãã
ã«ã¼ãã£ã³ã°ã®è¨å®ãæ£ããã確èªããããã«ãã¦ãã ããã
ä¾ãã°ãæ¬æ¥ã®ã³ã¼ãã§ããã°ã«ã¼ããã¹ / ã«å¯¾ãã¦ã¯Homeã³ã³ãã¼ãã³ãã/loginãã¹ã«å¯¾ãã¦ã¯Loginã³ã³ãã¼ãã³ãã/registerãã¹ã«å¯¾ãã¦ã¯Registerã³ã³ãã¼ãã³ãã/dashboardãã¹ã«å¯¾ãã¦ã¯Dashboardã³ã³ãã¼ãã³ããæå®ããã¦ãã¾ãã
ãããã®ã³ã³ãã¼ãã³ããæ£ããè¨å®ããã¦ãããã¨ã確èªãã¦ãã ããã
ã¾ãããã©ã¦ã¶ã§æ£ãããã¼ã¸ã§ã³ã®react-router-domããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ããã¦ããã確èªãã¦ãã ããã
ããã§ã®ã³ã¼ãã¯React Router v6ãæ³å®ãã¦ããããã対å¿ãããã¼ã¸ã§ã³ã®ããã±ã¼ã¸ã使ç¨ããå¿ è¦ãããã¾ãã
ãã¼ã¸ã§ã³ã®éãã«ã¤ãã¦ã¯ä»¥ä¸ãåç §ãã ããã
ã¾ããReact Routerã使ç¨ããã¨ãURLã®ãã¹ã«åºã¥ãã¦ç°ãªãã³ã³ãã¼ãã³ãã表示ãããã¨ãã§ãã¾ããã¦ã¼ã¶ã¼ããªã³ã¯ãã¯ãªãã¯ããã¨ãReact Routerã¯URLãå¤æ´ãã対å¿ããã³ã³ãã¼ãã³ããã¬ã³ããªã³ã°ãã¾ãã
ãã®ããã»ã¹ã¯ãã¯ã©ã¤ã¢ã³ããµã¤ãã§ã®ãã¼ã¸é·ç§»ãå®ç¾ãããããSPAã¢ããªã±ã¼ã·ã§ã³ã®ä¸é¨ã¨ãã¦è¦ãªããã¾ãã
SPAã¢ããªã±ã¼ã·ã§ã³ã¯ãã¦ã¼ã¶ã¼ã¨ã¯ã¹ããªã¨ã³ã¹ã®åä¸ãã¬ã¹ãã³ã¹æ§ã®åä¸ãªã©ã®å©ç¹ãæä¾ããä¸æ¹ã§ãååã®ãã¼ãæã«å¤§ããªJavaScriptãã³ãã«ããã¦ã³ãã¼ãããå¿ è¦ããããããååã®ãã¼ãæéãé·ããªãã¨ããæ¬ ç¹ãããã¾ãã®ã§ã注æãã ããã
ãã®ãSPAã¢ããªã±ã¼ã·ã§ã³ã®ååãã¼ãæéã®é·ãã¨ããæ¬ ç¹ã解決ããããã«ã¯ãSSRï¼Server-Side Renderingï¼ã¾ãã¯SSGï¼Static Site Generationï¼ã使ç¨ãããã¨ãä¸è¬çã§ãã
以ä¸ã§è§£èª¬ãã¦ãã¾ãã®ã§åç §ãã ããã
SSRã¨SSGã¯ãSPAã¢ããªã±ã¼ã·ã§ã³ã®ååãã¼ãæéãç縮ããããã©ã¼ãã³ã¹ãåä¸ãããæ¹æ³ã¨ãã¦æå¹ã§ããã©ã¡ããé¸æãããã¯ãã¢ããªã±ã¼ã·ã§ã³ã®è¦ä»¶ãã¦ã¼ã¶ã¼ã¨ã¯ã¹ããªã¨ã³ã¹ã®ç®æ¨ã«åºã¥ãã¦æ±ºå®ããå¿ è¦ãããã¾ãã
ã¾ããæ¬æ¥ã¯åç´åã«ããããã«CSS Modulesããã³é常ã®CSSã§ã®ã¹ã¿ã¤ãªã³ã°ãè¡ãã¾ããããReactã§ã¯ããã¼ã¯ã¢ã¼ãã®è¨å®ãä»ã®ã¹ã¿ã¤ãªã³ã°ã®å®è£ ã«ããã¦ãCSSãã¬ã¼ã ã¯ã¼ã¯ã®ä½¿ç¨ã¯ä¾¿å©ãªé¸æè¢ã§ãã
Tailwind CSSãªã©ã®CSSãã¬ã¼ã ã¯ã¼ã¯ã¯ãæ¢åã®ã¹ã¿ã¤ã«ãã³ã³ãã¼ãã³ããæ´»ç¨ããç°¡åã«ã«ã¹ã¿ãã¤ãºã§ãããããæåã§ã¹ã¿ã¤ãªã³ã°ãè¡ããããå¹ççã«å®è£ ãããã¨ãã§ãã¾ãã
ãã ããä»åã®ããã«èªèº«ã§ã¹ã¿ã¤ãªã³ã°ãå®è£ ãããã¨ãå®å ¨ã«å¯è½ã§ãã
ããã¸ã§ã¯ãã®è¦ä»¶ãã¹ã¿ã¤ãªã³ã°ã®ãã¼ãºã«å¿ãã¦ãCSSãã¬ã¼ã ã¯ã¼ã¯ã使ç¨ããããç¬èªã®ã¹ã¿ã¤ãªã³ã°ãå®è£ ããããé¸æãããã¨ãéè¦ã§ãã
ãããã®ç¹ã確èªãã¦ãå¿ è¦ãªä¿®æ£ã追å ãè¡ã£ã¦ãã ããã
æå¾ã«
ãã®ä¾ã§ã¯ãåç´ãªãã¼ã¯ã³ã®ä¿åã¨ãªãã¤ã¬ã¯ãã®å®è£ ãè¡ãã¾ããããå®éã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ã»ãã¥ãªãã£ã®è¦³ç¹ãããã¾ãã¾ãªå¯¾çãå¿ è¦ã§ãã
å®å ¨ãªãã¼ã¯ã³ã®çææ¹æ³ããããã¯ã¨ã³ããµã¼ãã¼ã¨ã®éä¿¡ã«ãããèªè¨¼ã®å®è£ ãªã©ãã»ãã¥ãªãã£ã«é¢ããè¦ç´ ãèæ ®ããå¿ è¦ãããã¾ãã
ãã®è¨äºã§ãReact.jsã®ããã¯ã使ç¨ãã¦ã¦ã¼ã¶ã¼èªè¨¼æ©è½ãæã¤ã·ã³ãã«ãªã¢ããªãä½æããèªè¨¼ããã¼ããã©ã¤ãã¼ãã«ã¼ãã®ä¿è·ããã¼ã¯ã³ã®ä¿åã«ã¤ãã¦ããªãã¯å¦ã³ã¾ããã
ãããã®æ©è½ãå®è£ ããéã«ã¯ããã³ãã¬ã¼ãã³ã¼ããåèã«ããå¿ è¦ã«å¿ãã¦ã¢ããªã±ã¼ã·ã§ã³ã«åããã¦ã«ã¹ã¿ãã¤ãºãæ¡å¼µãè¡ã£ã¦ãã ããã
å®å ¨ãªãã¼ã¯ã³ã®çææ¹æ³ã«ã¤ãã¦ã¯ãä¹±æ°çæãããã·ã¥é¢æ°ã®ä½¿ç¨ãªã©ãèæ ®ãããã¹ãã§ããã¾ããããã¯ã¨ã³ããµã¼ãã¼ã¨ã®éä¿¡ã«ãããèªè¨¼ã¯ãHTTPSãããã³ã«ã®ä½¿ç¨ããã¼ã¯ã³ã®æå¹æéã®ç®¡çãªã©ãéè¦ã§ãã
以ä¸ããReact.jsã使ç¨ãã¦ã¦ã¼ã¶ã¼èªè¨¼æ©è½ãæã¤ã·ã³ãã«ãªã¢ããªã®ä½æã¨ãèªè¨¼ããã¼ããã©ã¤ãã¼ãã«ã¼ãã®ä¿è·ããã¼ã¯ã³ã®ä¿åã«ã¤ãã¦ã®è§£èª¬ã§ããã
ãªããä»å¾ãªãã¡ã¯ã¿ãªã³ã°ã®è¨äºãæ稿ãããã¾ãããã®è¨äºã§ã¯ãReact Contextã使ç¨ããç¶æ 管çã³ã¼ãã«å¤æ´ããæ¹æ³ã«ã¤ãã¦è§£èª¬ãã¾ãã
æå¾ã¾ã§ãèªã¿ããã ãããããã¨ããããã¾ããã
ãã®è¨äºãå½¹ã«ç«ã£ãããããã¯ãã¼ã¯ã¨å ±æããã¦ããã ããã¨å¹¸ãã§ãã