useEffect
useEffect
ã¯ãã³ã³ããŒãã³ããå€éšã·ã¹ãã ãšåæãããããã® React ããã¯ã§ãã
useEffect(setup, dependencies?)
- ãªãã¡ã¬ã³ã¹
- 䜿çšæ³
- å€éšã·ã¹ãã ãžã®æ¥ç¶
- ã«ã¹ã¿ã ããã¯ã«ãšãã§ã¯ããã©ãããã
- é React ãŠã£ãžã§ããã®å¶åŸ¡
- ãšãã§ã¯ãã䜿ã£ãããŒã¿ãã§ãã
- ãªã¢ã¯ãã£ããªäŸåé åã®æå®
- ãšãã§ã¯ãå ã§ä»¥åã® state ã«åºã¥ã㊠state ãæŽæ°ãã
- ãªããžã§ã¯ãåã®äžèŠãªäŸåå€ãåé€ãã
- é¢æ°åã®äžèŠãªäŸåå€ãåé€ãã
- ãšãã§ã¯ãããææ°ã® props ãš state ãèªã¿åã
- ãµãŒããšã¯ã©ã€ã¢ã³ãã§ç°ãªãã³ã³ãã³ãã衚瀺ãã
- ãã©ãã«ã·ã¥ãŒãã£ã³ã°
- ã³ã³ããŒãã³ãã®ããŠã³ãæã«ãšãã§ã¯ãã 2 åå®è¡ããã
- ãšãã§ã¯ããåã¬ã³ããŒããšã«å®è¡ããã
- ãšãã§ã¯ããç¡éã«ãŒãã§åå®è¡ããç¶ãã
- ã³ã³ããŒãã³ããã¢ã³ããŠã³ããããŠããªãã®ã«ã¯ãªãŒã³ã¢ããããžãã¯ãå®è¡ããã
- ãšãã§ã¯ãã衚瀺ã«é¢ããããšãè¡ã£ãŠãããå®è¡åã«ã¡ãã€ããèŠããã
ãªãã¡ã¬ã³ã¹
useEffect(setup, dependencies?)
ã³ã³ããŒãã³ãã®ãããã¬ãã«ã§ useEffect
ãåŒã³åºããŠããšãã§ã¯ã (Effect) ã宣èšããŸãã
import { useEffect } from 'react';
import { createConnection } from './chat.js';
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [serverUrl, roomId]);
// ...
}
åŒæ°
-
setup
: ãšãã§ã¯ãã®ããžãã¯ãèšè¿°ãããé¢æ°ã§ãããã®ã»ããã¢ããé¢æ°ã¯ããªãã·ã§ã³ã§ã¯ãªãŒã³ã¢ããé¢æ°ãè¿ãããšãã§ããŸããã³ã³ããŒãã³ããåã㊠DOM ã«è¿œå ããããšãReact ã¯ã»ããã¢ããé¢æ°ãå®è¡ããŸããäŸåé å (dependencies) ãå€æŽãããåã¬ã³ããŒæã«ã¯ãReact ã¯ãŸãå€ãå€ã䜿ã£ãŠã¯ãªãŒã³ã¢ããé¢æ°ïŒããã°ïŒãå®è¡ãã次ã«æ°ããå€ã䜿ã£ãŠã»ããã¢ããé¢æ°ãå®è¡ããŸããã³ã³ããŒãã³ãã DOM ããåé€ãããåŸãReact ã¯ã¯ãªãŒã³ã¢ããé¢æ°ãæåŸã«ããäžåºŠå®è¡ããŸãã -
çç¥å¯èœ
dependencies
:setup
ã³ãŒãå ã§åç §ããããã¹ãŠã®ãªã¢ã¯ãã£ããªå€ã®ãªã¹ãã§ãããªã¢ã¯ãã£ããªå€ã«ã¯ãpropsãstateãã³ã³ããŒãã³ãæ¬äœã«çŽæ¥å®£èšããããã¹ãŠã®å€æ°ããã³é¢æ°ãå«ãŸããŸãããªã³ã¿ã React çšã«èšå®ãããŠããå Žåããã¹ãŠã®ãªã¢ã¯ãã£ããªå€ãäŸåå€ãšããŠæ£ããæå®ãããŠããã確èªã§ããŸããäŸåå€ã®ãªã¹ãã¯èŠçŽ æ°ãäžå®ã§ããå¿ èŠãããã[dep1, dep2, dep3]
ã®ããã«ã€ã³ã©ã€ã³ã§èšè¿°ããå¿ èŠããããŸããReact ã¯ãObject.is
ã䜿ã£ãæ¯èŒã§ãããããã®äŸåå€ã以åã®å€ãšæ¯èŒããŸãããã®åŒæ°ãçç¥ãããšããšãã§ã¯ãã¯ã³ã³ããŒãã³ãã®æ¯åã®ã¬ã³ããŒåŸã«åå®è¡ãããŸããäŸåå€ã®é åãæž¡ãå Žåãšç©ºã®é åãæž¡ãå Žåãããã³äœãæž¡ããªãå Žåã®éãã確èªããŠãã ããã
è¿ãå€
useEffect
㯠undefined
ãè¿ããŸãã
泚æç¹
-
useEffect
ã¯ããã¯ã§ãããããã³ã³ããŒãã³ãã®ãããã¬ãã«ãã«ã¹ã¿ã ããã¯å ã§ã®ã¿åŒã³åºãããšãã§ããŸããã«ãŒããæ¡ä»¶æã®äžã§åŒã³åºãããšã¯ã§ããŸããããããå¿ èŠãªå Žåã¯ãæ°ããã³ã³ããŒãã³ããæœåºãããã®äžã« state ã移åãããŠãã ããã -
å€éšã·ã¹ãã ãšåæããå¿ èŠããªãå Žåããšãã§ã¯ãã¯ããããäžèŠã§ãã
-
Strict Mode ãæå¹ãªå ŽåãReact ã¯æ¬ç©ã®ã»ããã¢ããã®åã«ãéçºæå°çšã®ã»ããã¢ãã+ã¯ãªãŒã³ã¢ãããµã€ã¯ã«ã 1 åè¿œå ã§å®è¡ããŸããããã¯ãã¯ãªãŒã³ã¢ããããžãã¯ãã»ããã¢ããããžãã¯ãšé¡ã®ããã«å¯Ÿå¿ããŠãããã»ããã¢ããã§è¡ãããããšãåæ¢ãŸãã¯å ã«æ»ããŠããããšãä¿èšŒããããã®ã¹ãã¬ã¹ãã¹ãã§ããåé¡ãçºçããå Žåã¯ãã¯ãªãŒã³ã¢ããé¢æ°ãå®è£ ããŸãã
-
äŸåé åã®äžéšã«ã³ã³ããŒãã³ãå ã§å®çŸ©ããããªããžã§ã¯ããé¢æ°ãããå Žåããšãã§ã¯ããå¿ èŠä»¥äžã«åå®è¡ãããå¯èœæ§ããããŸãããããä¿®æ£ããã«ã¯ããªããžã§ã¯ãåããã³é¢æ°åã®äžèŠãªäŸåå€ãåé€ããŸãããŸãããšãã§ã¯ãã®å€éšã« state ã®æŽæ°ãéãªã¢ã¯ãã£ããªããžãã¯ãæœåºããããšãã§ããŸãã
-
ãšãã§ã¯ãããŠãŒã¶æäœïŒã¯ãªãã¯ãªã©ïŒã«ãã£ãŠåŒãèµ·ãããããã®ã§ãªãå ŽåãReact ã¯ãã©ãŠã¶ãæ°ããç»é¢ãæç»ããåŸã«ãšãã§ã¯ããå®è¡ããŸããããªãã®ãšãã§ã¯ããïŒããŒã«ãããã®é 眮ãªã©ïŒäœãèŠèŠçãªäœæ¥ãè¡ã£ãŠããé 延ãç®ç«ã€å ŽåïŒã¡ãã€ããªã©ïŒã
useEffect
ãuseLayoutEffect
ã«çœ®ãæããŠãã ããã -
ãšãã§ã¯ãããŠãŒã¶æäœïŒã¯ãªãã¯ãªã©ïŒã«ãã£ãŠåŒãèµ·ããããå Žåã§ãããã©ãŠã¶ã¯ãšãã§ã¯ãå ã® state æŽæ°åŠçã®åã«ç»é¢ãåæç»ããå¯èœæ§ããããŸããéåžžããããæãŸããåäœã§ãããããããã©ãŠã¶ã«ããç»é¢ã®åæç»ããããã¯ããªããã°ãªããªãå Žåã
useEffect
ãuseLayoutEffect
ã«çœ®ãæããå¿ èŠããããŸãã -
ãšãã§ã¯ãã¯ã¯ã©ã€ã¢ã³ãäžã§ã®ã¿å®è¡ãããŸãããµãŒãã¬ã³ããªã³ã°äžã«ã¯å®è¡ãããŸããã
䜿çšæ³
å€éšã·ã¹ãã ãžã®æ¥ç¶
ã³ã³ããŒãã³ãã«ãã£ãŠã¯èªèº«ãããŒãžã«è¡šç€ºãããŠããéããããã¯ãŒã¯ãäœããã®ãã©ãŠã¶ APIããŸãã¯ãµãŒãããŒãã£ã©ã€ãã©ãªãšã®æ¥ç¶ãç¶æããå¿ èŠããããã®ããããŸãããããã®ã·ã¹ãã 㯠React ã«ãã£ãŠå¶åŸ¡ãããŠããªããããå€éš (external) ã®ãã®ã§ãã
ã³ã³ããŒãã³ããå€éšã·ã¹ãã ã«æ¥ç¶ããã«ã¯ãã³ã³ããŒãã³ãã®ãããã¬ãã«ã§ useEffect
ãåŒã³åºããŸãã
import { useEffect } from 'react';
import { createConnection } from './chat.js';
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [serverUrl, roomId]);
// ...
}
useEffect
ã«ã¯ 2 ã€ã®åŒæ°ãæž¡ãå¿
èŠããããŸãã
- ã·ã¹ãã ã«æ¥ç¶ããã»ããã¢ããã³ãŒããå«ãã»ããã¢ããé¢æ°ã
- ãã®ã·ã¹ãã ããåæããã¯ãªãŒã³ã¢ããã³ãŒããå«ãã¯ãªãŒã³ã¢ããé¢æ°ãè¿ãå¿ èŠããããŸãã
- ãããã®é¢æ°å ã§äœ¿çšãããã³ã³ããŒãã³ãããã®ãã¹ãŠã®å€ãå«ãã äŸåå€ã®ãªã¹ãã
React ã¯å¿ èŠã«å¿ããŠã»ããã¢ããé¢æ°ãšã¯ãªãŒã³ã¢ããé¢æ°ãåŒã³åºããããã¯è€æ°åè¡ãããããšããããŸãã
- ã³ã³ããŒãã³ããããŒãžã«è¿œå ïŒããŠã³ãïŒããããšãã»ããã¢ããã³ãŒããå®è¡ãããŸãã
- äŸåå€ãå€æŽãããäžã§ã³ã³ããŒãã³ããåã¬ã³ããŒããã床ã«ïŒ
- ãŸããå€ã props ãš state ã§ã¯ãªãŒã³ã¢ããã³ãŒããå®è¡ãããŸãã
- 次ã«ãæ°ãã props ãš state ã§ã»ããã¢ããã³ãŒããå®è¡ãããŸãã
- ã³ã³ããŒãã³ããããŒãžããåé€ïŒã¢ã³ããŠã³ãïŒããããšãæåŸã«ã¯ãªãŒã³ã¢ããã³ãŒããå®è¡ãããŸãã
äžèšã®äŸã§ãã®ã·ãŒã±ã³ã¹ã説æããŸãããã
äžèšã® ChatRoom
ã³ã³ããŒãã³ããããŒãžã«è¿œå ããããšãserverUrl
ãš roomId
ã®åæå€ã䜿ã£ãŠãã£ããã«ãŒã ã«æ¥ç¶ããŸããserverUrl
ãŸã㯠roomId
ãåã¬ã³ããŒã®çµæãšããŠå€æŽãããå ŽåïŒäŸãã°ããŠãŒã¶ãããããããŠã³ã§å¥ã®ãã£ããã«ãŒã ãéžæããå ŽåïŒãããªãã®ãšãã§ã¯ãã¯ä»¥åã®ã«ãŒã ããåæãã次ã®ã«ãŒã ã«æ¥ç¶ããŸããChatRoom
ã³ã³ããŒãã³ããããŒãžããåé€ããããšãããªãã®ãšãã§ã¯ãã¯æåŸã®åæãè¡ããŸãã
ãã°ãèŠã€ãåºãããã«ãéçºäžã«ã¯ React ã¯ã»ããã¢ãããšã¯ãªãŒã³ã¢ããããã»ããã¢ããã®åã« 1 åäœåã«å®è¡ããŸããããã¯ããšãã§ã¯ãã®ããžãã¯ãæ£ããå®è£ ãããŠããããšã確èªããã¹ãã¬ã¹ãã¹ãã§ãããããç®ã«èŠããåé¡ãåŒãèµ·ããå Žåãã¯ãªãŒã³ã¢ããé¢æ°ã«äžéšã®ããžãã¯ãæ¬ ããŠããŸããã¯ãªãŒã³ã¢ããé¢æ°ã¯ãã»ããã¢ããé¢æ°ãè¡ã£ãŠããããšãåæ¢ãªããå ã«æ»ãå¿ èŠããããŸããåºæ¬ã«ãŒã«ãšããŠããŠãŒã¶ã¯ã»ããã¢ãããäžåºŠããåŒã°ããŠããªãïŒæ¬çªç°å¢ã®å ŽåïŒããã»ããã¢ãã â ã¯ãªãŒã³ã¢ãã â ã»ããã¢ããã®ã·ãŒã±ã³ã¹ïŒéçºç°å¢ã®å ŽåïŒã§åŒã°ããŠããããåºå¥ã§ããªãããã«ããå¿ èŠããããŸããäžè¬çãªè§£æ±ºæ³ãåç §ããŠãã ããã
åãšãã§ã¯ããç¬ç«ããããã»ã¹ãšããŠèšè¿°ããããã«ããäžåã®ã»ããã¢ããïŒã¯ãªãŒã³ã¢ããã®ãµã€ã¯ã«ã ããèããããã«ããŠãã ãããã³ã³ããŒãã³ããçŸåšããŠã³ããæŽæ°ãã¢ã³ããŠã³ãã®ã©ããè¡ã£ãŠããããèæ ®ãã¹ãã§ã¯ãããŸãããã»ããã¢ããããžãã¯ãæ£ããã¯ãªãŒã³ã¢ããããžãã¯ãšã察å¿ããããããšã§ããšãã§ã¯ãã¯ã»ããã¢ãããšã¯ãªãŒã³ã¢ãããå¿ èŠã«å¿ããŠäœåºŠå®è¡ããŠãåé¡ãèµ·ããªããå ç¢ãªãã®ãšãªããŸãã
äŸ 1/5: ãã£ãããµãŒããžã®æ¥ç¶
ãã®äŸã§ã¯ãChatRoom
ã³ã³ããŒãã³ãããšãã§ã¯ãã䜿ã£ãŠ chat.js
ã§å®çŸ©ãããå€éšã·ã¹ãã ã«æ¥ç¶ããŠããŸããâOpen chatâ ãæŒããš ChatRoom
ã³ã³ããŒãã³ãã衚瀺ãããŸãããã®ãµã³ãããã¯ã¹ã¯éçºã¢ãŒãã§å®è¡ãããŠããããããã¡ãã§èª¬æãããŠããããã«ãæ¥ç¶ãšåæã®ãµã€ã¯ã«ã 1 åè¿œå ã§çºçããŸããroomId
ãš serverUrl
ãããããããŠã³ãšå
¥åæ¬ã§å€æŽããŠããšãã§ã¯ãããã£ããã«åæ¥ç¶ããæ§åã確èªããŠã¿ãŠãã ãããâClose chatâ ãæŒããšããšãã§ã¯ããæåŸã® 1 åã®åæäœæ¥ãè¡ããŸãã
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => { connection.disconnect(); }; }, [roomId, serverUrl]); return ( <> <label> Server URL:{' '} <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} /> </label> <h1>Welcome to the {roomId} room!</h1> </> ); } export default function App() { const [roomId, setRoomId] = useState('general'); const [show, setShow] = useState(false); return ( <> <label> Choose the chat room:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> </label> <button onClick={() => setShow(!show)}> {show ? 'Close chat' : 'Open chat'} </button> {show && <hr />} {show && <ChatRoom roomId={roomId} />} </> ); }
ã«ã¹ã¿ã ããã¯ã«ãšãã§ã¯ããã©ãããã
ãšãã§ã¯ãã¯ãé¿é£ããããã§ããReact ã®å€ã«åºãå¿ èŠãããããã€ç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã«å¯ŸããŠããè¯ãçµã¿èŸŒã¿ã®ãœãªã¥ãŒã·ã§ã³ããªãå Žåã«äœ¿çšããŸãããšãã§ã¯ããæã§äœåºŠãæžãå¿ èŠãããããšã«æ°ä»ããããéåžžããã¯ãããªãã®ã³ã³ããŒãã³ããäŸåããå ±éã®æ¯ãèãã®ããã®ã«ã¹ã¿ã ããã¯ãæœåºããå¿ èŠããããšãããµã€ã³ã§ãã
äŸãã°ããã® useChatRoom
ã«ã¹ã¿ã ããã¯ã¯ããšãã§ã¯ãã®ããžãã¯ããã宣èšç㪠API ã®èåŸã«ãé èœãããŸãã
function useChatRoom({ serverUrl, roomId }) {
useEffect(() => {
const options = {
serverUrl: serverUrl,
roomId: roomId
};
const connection = createConnection(options);
connection.connect();
return () => connection.disconnect();
}, [roomId, serverUrl]);
}
ãã®åŸã§ãä»»æã®ã³ã³ããŒãã³ããã以äžã®ããã«äœ¿ãããšãã§ããŸãã
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useChatRoom({
roomId: roomId,
serverUrl: serverUrl
});
// ...
ã»ãã«ã React ã®ãšã³ã·ã¹ãã ã«ã¯ãããŸããŸãªç®çã®ããã®åªããã«ã¹ã¿ã ããã¯ãå€æ°å ¬éãããŠããŸãã
ã«ã¹ã¿ã ããã¯ã§ãšãã§ã¯ããã©ããããæ¹æ³ã«ã€ããŠãã£ãšåŠã¶
äŸ 1/3: ã«ã¹ã¿ã useChatRoom
ããã¯
ãã®äŸã¯ããããŸã§ã®äŸ ã®ãããããšåãã§ãããã«ã¹ã¿ã ããã¯ã«ããžãã¯ãæœåºãããŠããŸãã
import { useState } from 'react'; import { useChatRoom } from './useChatRoom.js'; function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); useChatRoom({ roomId: roomId, serverUrl: serverUrl }); return ( <> <label> Server URL:{' '} <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} /> </label> <h1>Welcome to the {roomId} room!</h1> </> ); } export default function App() { const [roomId, setRoomId] = useState('general'); const [show, setShow] = useState(false); return ( <> <label> Choose the chat room:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> </label> <button onClick={() => setShow(!show)}> {show ? 'Close chat' : 'Open chat'} </button> {show && <hr />} {show && <ChatRoom roomId={roomId} />} </> ); }
é React ãŠã£ãžã§ããã®å¶åŸ¡
å€éšã·ã¹ãã ãããªãã®ã³ã³ããŒãã³ãã® props ã state ã«åæããããããšããããŸãã
äŸãã°ãReact ã䜿ã£ãŠããªããµãŒãããŒãã£è£œã®ããããŠã£ãžã§ããããããªãã¬ãŒã€ã³ã³ããŒãã³ããããå Žåããšãã§ã¯ãã䜿ã£ãŠãã¡ãã®ã¡ãœãããåŒã³åºãããã¡ãã®ç¶æ
ã React ã³ã³ããŒãã³ãã®çŸåš state ã«åãããããšãã§ããŸãã以äžã§ã¯ãmap-widget.js
ã«å®çŸ©ããã MapWidget
ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ããšãã§ã¯ããäœæããŸããMap
ã³ã³ããŒãã³ãã® props ã§ãã zoomLevel
ãå€æŽããããšããšãã§ã¯ããã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ã® setZoom()
ãåŒã³åºããŠãåæãä¿ã¡ãŸãã
import { useRef, useEffect } from 'react'; import { MapWidget } from './map-widget.js'; export default function Map({ zoomLevel }) { const containerRef = useRef(null); const mapRef = useRef(null); useEffect(() => { if (mapRef.current === null) { mapRef.current = new MapWidget(containerRef.current); } const map = mapRef.current; map.setZoom(zoomLevel); }, [zoomLevel]); return ( <div style={{ width: 200, height: 200 }} ref={containerRef} /> ); }
ãã®äŸã§ã¯ãã¯ãªãŒã³ã¢ããé¢æ°ã¯å¿
èŠãããŸããããªããªããMapWidget
ã¯ã©ã¹ã¯èªèº«ã«æž¡ããã DOM ããŒãã®ã¿ã管çããŠããããã§ããReact ã® Map
ã³ã³ããŒãã³ããããªãŒããåé€ãããåŸãDOM ããŒããš MapWidget
ã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ã¯ããã©ãŠã¶ã® JavaScript ãšã³ãžã³ã«ãã£ãŠèªåçã«ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããŸãã
ãšãã§ã¯ãã䜿ã£ãããŒã¿ãã§ãã
ãšãã§ã¯ãã䜿ã£ãŠãã³ã³ããŒãã³ãã«å¿ èŠãªããŒã¿ããã§ããïŒfetch, ååŸïŒããããšãã§ããŸãããã ããã¬ãŒã ã¯ãŒã¯ã䜿çšããŠããå Žåã¯ããšãã§ã¯ããèªåã§èšè¿°ãããããããã¬ãŒã ã¯ãŒã¯ã®ããŒã¿ãã§ããã¡ã«ããºã ã䜿çšããæ¹ãã¯ããã«å¹ççã§ããããšã«æ³šæããŠãã ããã
ãšãã§ã¯ãã䜿ã£ãŠèªåã§ããŒã¿ããã§ãããããå Žåã¯ã以äžã®ãããªã³ãŒããæžãããšã«ãªããŸãã
import { useState, useEffect } from 'react';
import { fetchBio } from './api.js';
export default function Page() {
const [person, setPerson] = useState('Alice');
const [bio, setBio] = useState(null);
useEffect(() => {
let ignore = false;
setBio(null);
fetchBio(person).then(result => {
if (!ignore) {
setBio(result);
}
});
return () => {
ignore = true;
};
}, [person]);
// ...
ignore
å€æ°ã«æ³šç®ããŠãã ããããã㯠false
ã§åæåãããã¯ãªãŒã³ã¢ããæã« true
ã«èšå®ãããŸããããã«ãããã³ãŒãã â競åç¶æ
(race condition)â ã«æ©ãŸãããªãããã«ãªããŸãããããã¯ãŒã¯ã¬ã¹ãã³ã¹ã¯ãéä¿¡ããé åºãšç°ãªãé åºã§å±ãããšãããããšã«æ³šæããŸãããã
import { useState, useEffect } from 'react'; import { fetchBio } from './api.js'; export default function Page() { const [person, setPerson] = useState('Alice'); const [bio, setBio] = useState(null); useEffect(() => { let ignore = false; setBio(null); fetchBio(person).then(result => { if (!ignore) { setBio(result); } }); return () => { ignore = true; } }, [person]); return ( <> <select value={person} onChange={e => { setPerson(e.target.value); }}> <option value="Alice">Alice</option> <option value="Bob">Bob</option> <option value="Taylor">Taylor</option> </select> <hr /> <p><i>{bio ?? 'Loading...'}</i></p> </> ); }
ãŸããasync
/ await
æ§æã䜿ã£ãŠæžãçŽãããšãã§ããŸããããã®å Žåã§ãã¯ãªãŒã³ã¢ããé¢æ°ãæž¡ãå¿
èŠããããŸãã
import { useState, useEffect } from 'react'; import { fetchBio } from './api.js'; export default function Page() { const [person, setPerson] = useState('Alice'); const [bio, setBio] = useState(null); useEffect(() => { async function startFetching() { setBio(null); const result = await fetchBio(person); if (!ignore) { setBio(result); } } let ignore = false; startFetching(); return () => { ignore = true; } }, [person]); return ( <> <select value={person} onChange={e => { setPerson(e.target.value); }}> <option value="Alice">Alice</option> <option value="Bob">Bob</option> <option value="Taylor">Taylor</option> </select> <hr /> <p><i>{bio ?? 'Loading...'}</i></p> </> ); }
ãšãã§ã¯ãå ã§çŽæ¥ããŒã¿ãã§ãããæžããšã³ãŒãã®ç¹°ãè¿ããå¢ãããã£ãã·ã¥ããµãŒãã¬ã³ããªã³ã°ãšãã£ãæé©åãåŸããè¿œå ããããšãé£ãããªããŸããç¬èªã®ããããã¯ã³ãã¥ããã£ãã¡ã³ããã³ã¹ããŠããã«ã¹ã¿ã ããã¯ã䜿ãæ¹ãç°¡åã§ãã
ããã«æ·±ãç¥ã
ç¹ã«å®å
šã«ã¯ã©ã€ã¢ã³ããµã€ãã®ã¢ããªã«ãããŠã¯ããšãã§ã¯ãã®äžã§ fetch
ã³ãŒã«ãæžãããšã¯ããŒã¿ãã§ããã®äžè¬çãªæ¹æ³ã§ããããããããã¯éåžžã«æäœæ¥é Œãã®ã¢ãããŒãã§ããã倧ããªæ¬ ç¹ããããŸãã
- ãšãã§ã¯ãã¯ãµãŒãäžã§ã¯åäœããŸãããããã¯ããµãŒãã¬ã³ããªã³ã°ãããåæ HTML ã«ã¯ããŒã¿ã®ãªãããŒãã£ã³ã°äžãšãã衚瀺ã®ã¿ãå«ãŸããŠããŸãããšãæå³ããŸããã¯ã©ã€ã¢ã³ãã®ã³ã³ãã¥ãŒã¿ã¯ããã¹ãŠã® JavaScript ãããŠã³ããŒãããã¢ããªãã¬ã³ããŒããåŸã«ãªã£ãŠãã£ãšãä»åºŠã¯ããŒã¿ãèªã¿èŸŒãå¿ èŠããããšããããšã«æ°ä»ãããšã«ãªããŸããããã¯ããŸãå¹ççã§ã¯ãããŸããã
- ãšãã§ã¯ãã§çŽæ¥ããŒã¿ãã§ãããè¡ããšãããããã¯ãŒã¯ã®ãŠã©ãŒã¿ãŒãã©ãŒã«ïŒæ»ïŒããäœæãããããªããŸãã芪ã³ã³ããŒãã³ããã¬ã³ããŒãããããäœãããŒã¿ããã§ããããããã«ãã£ãŠåã³ã³ããŒãã³ããã¬ã³ããŒããä»åºŠã¯ãããäœãããŒã¿ã®ãã§ãããéå§ããããšãã£ãå ·åã§ãããããã¯ãŒã¯ãããŸãéããªãå Žåãããã¯ãã¹ãŠã®ããŒã¿ã䞊è¡ã§ååŸãããããããªãé ããªããŸãã
- ãšãã§ã¯ãå ã§çŽæ¥ããŒã¿ãã§ãããããšããããšã¯ããããããŒã¿ãããªããŒãããã£ãã·ã¥ãããŠããªããšããããšã§ããäŸãã°ãã³ã³ããŒãã³ããã¢ã³ããŠã³ããããåŸã«åã³ããŠã³ããããå ŽåãããŒã¿ãå床ååŸããå¿ èŠããããŸãã
- 人ã«ãšã£ãŠæžããããã³ãŒãã«ãªããŸããã競åç¶æ
ã®ãããªãã°ãèµ·ãããªãããã«
fetch
ã³ãŒã«ãæžãããšãããšãããªãã®ãã€ã©ãŒãã¬ãŒãã³ãŒããå¿ èŠã§ãã
äžèšã®æ¬ ç¹ã¯ãããŠã³ãæã«ããŒã¿ããã§ããããã®ã§ããã°ãReact ã«éããã©ã®ã©ã€ãã©ãªã䜿ãå Žåã§ãåœãŠã¯ãŸãå 容ã§ããã«ãŒãã£ã³ã°ãšåæ§ãããŒã¿ãã§ããã®å®è£ ãäžæã«ããããšãããšäžççžã§ã¯ãããŸãããç§ãã¡ã¯ä»¥äžã®ã¢ãããŒãããå§ãããŸãã
- ãã¬ãŒã ã¯ãŒã¯ã䜿çšããŠããå Žåãçµã¿èŸŒã¿ã®ããŒã¿ãã§ããæ©æ§ã䜿çšããŠãã ãããã¢ãã³ãª React ãã¬ãŒã ã¯ãŒã¯ã«ã¯ãå¹ççã§äžèšã®æ¬ ç¹ããªãããŒã¿ãã§ããæ©æ§ãçµ±åãããŠããŸãã
- ãã以å€ã®å Žåã¯ãã¯ã©ã€ã¢ã³ããµã€ããã£ãã·ã¥ã®äœ¿çšãæ§ç¯ãæ€èšããŠãã ãããäžè¬çãªãªãŒãã³ãœãŒã¹ã®ãœãªã¥ãŒã·ã§ã³ã«ã¯ãReact QueryãuseSWRãããã³ React Router 6.4+ ãå«ãŸããŸããèªåã§ãœãªã¥ãŒã·ã§ã³ãæ§ç¯ããããšãã§ããŸãããã®å Žåããšãã§ã¯ããå éšã§äœ¿çšãã€ã€ããªã¯ãšã¹ãã®éè€æé€ãã¬ã¹ãã³ã¹ã®ãã£ãã·ã¥ããããã¯ãŒã¯ã®ãŠã©ãŒã¿ãŒãã©ãŒã«ãåé¿ããããã®ããžãã¯ïŒããŒã¿ã®ããªããŒããã«ãŒãã£ã³ã°éšãžã®ããŒã¿èŠæ±ã®å·»ãäžãïŒãè¿œå ããããšã«ãªããŸãã
ãããã®ã¢ãããŒããã©ã¡ããé©åããªãå Žåã¯ãåŒãç¶ããšãã§ã¯ãå ã§çŽæ¥ããŒã¿ããã§ããããããšãã§ããŸãã
ãªã¢ã¯ãã£ããªäŸåé åã®æå®
ãšãã§ã¯ãã®äŸåé åã¯ãèªåã§ãéžã¶ããããã®ç©ã§ã¯ãªãããšã«æ³šæããŠãã ããããšãã§ã¯ãã®ã³ãŒãã«ãã£ãŠäœ¿çšããããã¹ãŠã®ãªã¢ã¯ãã£ããªå€ã¯ãäŸåå€ãšããŠå®£èšãããªããã°ãªããŸããããšãã§ã¯ãã®äŸåå€ã®ãªã¹ãã¯ãåšå²ã®ã³ãŒãã«ãã£ãŠæ±ºå®ãããŸãã
function ChatRoom({ roomId }) { // This is a reactive value
const [serverUrl, setServerUrl] = useState('https://localhost:1234'); // This is a reactive value too
useEffect(() => {
const connection = createConnection(serverUrl, roomId); // This Effect reads these reactive values
connection.connect();
return () => connection.disconnect();
}, [serverUrl, roomId]); // â
So you must specify them as dependencies of your Effect
// ...
}
serverUrl
ãŸã㯠roomId
ãå€æŽããããšããšãã§ã¯ãã¯æ°ããå€ã䜿çšããŠãã£ããã«åæ¥ç¶ããŸãã
ãªã¢ã¯ãã£ããªå€ã«ã¯ãprops ãšãã³ã³ããŒãã³ãå
ã«çŽæ¥å®£èšããããã¹ãŠã®å€æ°ããã³é¢æ°ãå«ãŸããŸããroomId
ãš serverUrl
ã¯ãªã¢ã¯ãã£ããªå€ã§ãããããäŸåå€ã®ãªã¹ãããåé€ããããšã¯ã§ããŸãããããããçç¥ããããšããå ŽåãReact çšã®ãªã³ã¿ãæ£ããèšå®ãããŠããã°ããªã³ã¿ã¯ãããä¿®æ£ãå¿
èŠãªèª€ãã§ãããšææããŸãã
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, []); // ðŽ React Hook useEffect has missing dependencies: 'roomId' and 'serverUrl'
// ...
}
äŸåé
åããäœããåé€ããã«ã¯ããªã³ã¿ã«å¯ŸãããããäŸåå€ã§ããçç±ããªãããšãã蚌æãããå¿
èŠããããŸããäŸãã°ãserverUrl
ãã³ã³ããŒãã³ãã®å€ã«ç§»åããã°ãããããªã¢ã¯ãã£ããªå€ã§ã¯ãªããåã¬ã³ããŒæã«å€æŽãããªããã®ã§ããããšã蚌æã§ããŸãã
const serverUrl = 'https://localhost:1234'; // Not a reactive value anymore
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]); // â
All dependencies declared
// ...
}
ãã㧠serverUrl
ããªã¢ã¯ãã£ããªå€ã§ãªããªã£ãïŒåã¬ã³ããŒæã«å€æŽãããªãïŒãããäŸåé
åã«å
¥ããå¿
èŠããªããªããŸããããšãã§ã¯ãã®ã³ãŒãããªã¢ã¯ãã£ããªå€ã䜿çšããŠããªãå Žåããã®äŸåé
åã¯ç©º ([]
) ã§ããã¹ãã§ãã
const serverUrl = 'https://localhost:1234'; // Not a reactive value anymore
const roomId = 'music'; // Not a reactive value anymore
function ChatRoom() {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, []); // â
All dependencies declared
// ...
}
空ã®äŸåé åã§å®çŸ©ãããšãã§ã¯ãã¯ãã³ã³ããŒãã³ãã® props ã state ãå€æŽãããå Žåã§ãåå®è¡ãããŸããã
äŸ 1/3: äŸåé
åãæž¡ã
äŸåé åãæå®ãããšããšãã§ã¯ãã¯æåã®ã¬ã³ããŒåŸããã³äŸåé åãå€ãã£ãåŸã®åã¬ã³ããŒåŸã«å®è¡ãããŸãã
useEffect(() => {
// ...
}, [a, b]); // Runs again if a or b are different
以äžã®äŸã§ã¯ãserverUrl
ãš roomId
㯠ãªã¢ã¯ãã£ããªå€ã§ãããããäž¡æ¹ãšãäŸåé
åã®äžã§æå®ããå¿
èŠããããŸãããã®çµæãããããããŠã³ã§å¥ã®ã«ãŒã ãéžæãããããµãŒã URL ã®å
¥åæ¬ãç·šéããããããšããã£ãããåæ¥ç¶ãããŸãããã ããmessage
ã¯ãšãã§ã¯ãã§äœ¿çšãããŠããªãïŒäŸåããå€ã§ã¯ãªãïŒãããã¡ãã»ãŒãžãç·šéããŠããã£ãããåæ¥ç¶ãããããšã¯ãããŸããã
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); const [message, setMessage] = useState(''); useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => { connection.disconnect(); }; }, [serverUrl, roomId]); return ( <> <label> Server URL:{' '} <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} /> </label> <h1>Welcome to the {roomId} room!</h1> <label> Your message:{' '} <input value={message} onChange={e => setMessage(e.target.value)} /> </label> </> ); } export default function App() { const [show, setShow] = useState(false); const [roomId, setRoomId] = useState('general'); return ( <> <label> Choose the chat room:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> <button onClick={() => setShow(!show)}> {show ? 'Close chat' : 'Open chat'} </button> </label> {show && <hr />} {show && <ChatRoom roomId={roomId}/>} </> ); }
ãšãã§ã¯ãå ã§ä»¥åã® state ã«åºã¥ã㊠state ãæŽæ°ãã
ãšãã§ã¯ããã以åã® state ã«åºã¥ã㊠state ãæŽæ°ãããå Žåãåé¡ãçºçãããããããŸããã
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const intervalId = setInterval(() => {
setCount(count + 1); // You want to increment the counter every second...
}, 1000)
return () => clearInterval(intervalId);
}, [count]); // ð© ... but specifying `count` as a dependency always resets the interval.
// ...
}
count
ã¯ãªã¢ã¯ãã£ããªå€ãªã®ã§ãäŸåé
åã«æå®ããå¿
èŠããããŸãããã ãããã®ãŸãŸã§ã¯ count
ãå€æŽããããã³ã«ããšãã§ã¯ããã¯ãªãŒã³ã¢ãããšã»ããã¢ãããç¹°ãè¿ãããšã«ãªããŸããããã¯æãŸãããããŸããã
ãã®åé¡ã解決ããã«ã¯ãsetCount
ã« c => c + 1
ãšãã state æŽæ°çšé¢æ°ãæž¡ããŸãã
import { useState, useEffect } from 'react'; export default function Counter() { const [count, setCount] = useState(0); useEffect(() => { const intervalId = setInterval(() => { setCount(c => c + 1); // â Pass a state updater }, 1000); return () => clearInterval(intervalId); }, []); // â Now count is not a dependency return <h1>{count}</h1>; }
c => c + 1
ã count + 1
ã®ä»£ããã«æž¡ãããã«ãªã£ãã®ã§ããã®ãšãã§ã¯ãã¯ãã count
ã«äŸåããå¿
èŠã¯ãããŸããããã®ä¿®æ£ã®çµæãcount
ãå€åãããã³ã«ã€ã³ã¿ãŒãã«ã®ã¯ãªãŒã³ã¢ãããšã»ããã¢ãããè¡ããªããŠããããªããŸãã
ãªããžã§ã¯ãåã®äžèŠãªäŸåå€ãåé€ãã
ãšãã§ã¯ããã¬ã³ããŒäžã«äœæããããªããžã§ã¯ããé¢æ°ã«äŸåããŠããå Žåãå¿
èŠä»¥äžã«ãšãã§ã¯ããå®è¡ãããŠããŸãããšããããŸããããšãã°ããã®ãšãã§ã¯ã㯠options
ãªããžã§ã¯ããã¬ã³ããŒããšã«ç°ãªããããæ¯åã®ã¬ã³ããŒåŸã«åæ¥ç¶ãè¡ã£ãŠããŸããŸãïŒ
const serverUrl = 'https://localhost:1234';
function ChatRoom({ roomId }) {
const [message, setMessage] = useState('');
const options = { // ð© This object is created from scratch on every re-render
serverUrl: serverUrl,
roomId: roomId
};
useEffect(() => {
const connection = createConnection(options); // It's used inside the Effect
connection.connect();
return () => connection.disconnect();
}, [options]); // ð© As a result, these dependencies are always different on a re-render
// ...
ã¬ã³ããŒäžã«æ°ãã«äœæããããªããžã§ã¯ããäŸåå€ãšããŠäœ¿çšããªãã§ãã ããã代ããã«ããšãã§ã¯ãã®äžã§ãªããžã§ã¯ããäœæããŸãïŒ
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId }) { const [message, setMessage] = useState(''); useEffect(() => { const options = { serverUrl: serverUrl, roomId: roomId }; const connection = createConnection(options); connection.connect(); return () => connection.disconnect(); }, [roomId]); return ( <> <h1>Welcome to the {roomId} room!</h1> <input value={message} onChange={e => setMessage(e.target.value)} /> </> ); } export default function App() { const [roomId, setRoomId] = useState('general'); return ( <> <label> Choose the chat room:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> </label> <hr /> <ChatRoom roomId={roomId} /> </> ); }
ãšãã§ã¯ãã®äžã§ options
ãªããžã§ã¯ããäœæããããã«ãªã£ãã®ã§ããšãã§ã¯ãèªäœã¯ roomId
æååã«ããäŸåããŸããã
ãã®ä¿®æ£ã«ãããå
¥åãã£ãŒã«ãã«æåãå
¥åããŠããã£ãããåæ¥ç¶ãããããšã¯ãªããªããŸãããªããžã§ã¯ãã¯åã¬ã³ããŒã®ãã³ã«åäœæãããã®ãšã¯ç°ãªããroomId
ã®ãããªæååã¯å¥ã®å€ã«èšå®ããªãéãå€æŽãããŸãããäŸåå€ã®åé€ã«é¢ãã詳现ãèªãã
é¢æ°åã®äžèŠãªäŸåå€ãåé€ãã
ãšãã§ã¯ããã¬ã³ããŒäžã«äœæããããªããžã§ã¯ããé¢æ°ã«äŸåããŠããå Žåãå¿
èŠä»¥äžã«ãšãã§ã¯ããå®è¡ãããŠããŸãããšããããŸããããšãã°ããã®ãšãã§ã¯ã㯠createOptions
é¢æ°ãã¬ã³ããŒããšã«ç°ãªããããæ¯ååæ¥ç¶ãè¡ã£ãŠããŸããŸãïŒ
function ChatRoom({ roomId }) {
const [message, setMessage] = useState('');
function createOptions() { // ð© This function is created from scratch on every re-render
return {
serverUrl: serverUrl,
roomId: roomId
};
}
useEffect(() => {
const options = createOptions(); // It's used inside the Effect
const connection = createConnection();
connection.connect();
return () => connection.disconnect();
}, [createOptions]); // ð© As a result, these dependencies are always different on a re-render
// ...
åã¬ã³ããŒã®ãã³ã«æ°ããé¢æ°ãäœæããããšãããèªäœã«ã¯åé¡ã¯ãªããæé©åããããšããå¿ èŠã¯ãããŸããããã ãããšãã§ã¯ãã®äŸåå€ãšããŠããã䜿çšããå Žåãæ¯åã®ã¬ã³ããŒåŸã«ãšãã§ã¯ããåå®è¡ãããŠããŸãããšã«ãªããŸãã
ã¬ã³ããŒäžã«äœæãããé¢æ°ãäŸåå€ãšããŠäœ¿çšããããšã¯é¿ããŠãã ããã代ããã«ããšãã§ã¯ãã®å éšã§å®£èšããããã«ããŸãã
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId }) { const [message, setMessage] = useState(''); useEffect(() => { function createOptions() { return { serverUrl: serverUrl, roomId: roomId }; } const options = createOptions(); const connection = createConnection(options); connection.connect(); return () => connection.disconnect(); }, [roomId]); return ( <> <h1>Welcome to the {roomId} room!</h1> <input value={message} onChange={e => setMessage(e.target.value)} /> </> ); } export default function App() { const [roomId, setRoomId] = useState('general'); return ( <> <label> Choose the chat room:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> </label> <hr /> <ChatRoom roomId={roomId} /> </> ); }
createOptions
é¢æ°ããšãã§ã¯ãå
ã§å®çŸ©ããããã«ããã®ã§ããšãã§ã¯ãèªäœã¯ roomId
æååã«ã®ã¿äŸåããããšã«ãªããŸãããã®ä¿®æ£ã«ãããå
¥åæ¬ã«å
¥åããŠããã£ãããåæ¥ç¶ãããªããªããŸããåã¬ã³ããŒæã«åäœæãããé¢æ°ãšã¯ç°ãªããroomId
ã®ãããªæååã¯ä»ã®å€ã«èšå®ããªãéãå€æŽãããŸãããäŸåå€ã®åé€ã«ã€ããŠè©³ããã¯ãã¡ãã
ãšãã§ã¯ãããææ°ã® props ãš state ãèªã¿åã
ããã©ã«ãã§ã¯ããšãã§ã¯ããããªã¢ã¯ãã£ããªå€ãèªã¿åããšãã¯ããããäŸåå€ãšããŠè¿œå ããå¿ èŠããããŸããããã«ããããšãã§ã¯ãã¯ãã®å€ã®å€æŽã«å¯ŸããŠãåå¿ãããããšãä¿èšŒãããŸããã»ãšãã©ã®äŸåå€ã«ã€ããŠã¯ããããæãæåã§ãã
ãã ããæã«ã¯ãåå¿ããããã«ææ°ã® props ã state ã ãšãã§ã¯ãå ããèªã¿åãããããšãããã§ããããäŸãã°ãã·ã§ããã³ã°ã«ãŒãå ã®ã¢ã€ãã æ°ãããŒãžèšªåããšã«èšé²ããå Žåãæ³åããŠã¿ãŠãã ããã
function Page({ url, shoppingCart }) {
useEffect(() => {
logVisit(url, shoppingCart.length);
}, [url, shoppingCart]); // â
All dependencies declared
// ...
}
url
ã®å€æŽããšã«æ°ããããŒãžèšªåãèšé²ãããããshoppingCart
ã®å€æŽã®ã¿ã§ã¯èšé²ããããªãå Žåã¯ã©ãããã°ããã®ã§ããããïŒ ãªã¢ã¯ãã£ãã«ãŒã«ã«åããããšãªã shoppingCart
ãäŸåé
åããé€å€ããããšã¯ã§ããŸããããããããšãã§ã¯ãå
ããåŒã°ããã³ãŒãã®äžéšã§ããã«ããããããããã®ã³ãŒããå€æŽã«ãåå¿ãããªãããšã瀺ãããšãã§ããŸããuseEffectEvent
ããã¯ã䜿çšããŠããšãã§ã¯ãã€ãã³ã (effect event) ã宣èšããshoppingCart
ãèªã¿åãã³ãŒãããã®å
éšã«ç§»åããŠãã ããã
function Page({ url, shoppingCart }) {
const onVisit = useEffectEvent(visitedUrl => {
logVisit(visitedUrl, shoppingCart.length)
});
useEffect(() => {
onVisit(url);
}, [url]); // â
All dependencies declared
// ...
}
ãšãã§ã¯ãã€ãã³ãã¯ãªã¢ã¯ãã£ãã§ãªã¯ããããããªãã®ãšãã§ã¯ãã®äŸåé
åããã¯åžžã«é€ãå¿
èŠããããŸããããã«ãããéãªã¢ã¯ãã£ããªã³ãŒãïŒææ°ã® props ã state ã®å€ãèªãããšãã§ããã³ãŒãïŒããšãã§ã¯ãã€ãã³ãå
ã«å
¥ããããšãã§ããŸããonVisit
ã®äžã§ shoppingCart
ãèªãããšã§ãshoppingCart
ããšãã§ã¯ããåå®è¡ããããšããªããªããŸãã
ãµãŒããšã¯ã©ã€ã¢ã³ãã§ç°ãªãã³ã³ãã³ãã衚瀺ãã
ã䜿ãã®ã¢ããªããµãŒãã¬ã³ããªã³ã°ãïŒçŽæ¥ãªãããã¬ãŒã ã¯ãŒã¯çµç±ã§ïŒäœ¿çšããŠããå Žåãã³ã³ããŒãã³ã㯠2 çš®é¡ã®ç°å¢ã§ã¬ã³ããŒãããŸãããµãŒãäžã§ã¯ãåæ HTML ãçæããããã«ã¬ã³ããŒãããŸããã¯ã©ã€ã¢ã³ãäžã§ã¯ãReact ããã® HTML ã«ã€ãã³ããã³ãã©ãã¢ã¿ããããããã«å床ã¬ã³ããŒã³ãŒããå®è¡ããŸãããããããã€ãã¬ãŒã·ã§ã³ãåäœããããã«ã¯ååã¬ã³ããŒã®åºåãã¯ã©ã€ã¢ã³ããšãµãŒãã®äž¡æ¹ã§åäžã§ãªããã°ãªããªãçç±ã§ãã
ãŸãã«ãã¯ã©ã€ã¢ã³ãåŽã§ç°ãªãã³ã³ãã³ãã衚瀺ããå¿
èŠãããå ŽåããããŸããããšãã°ãã¢ããªã localStorage
ããããŒã¿ãèªã¿èŸŒãå ŽåããµãŒãäžã§ã¯ãããè¡ãããšãã§ããŸãããããã¯ä»¥äžã®æ¹æ³ã§å®è£
ã§ããŸãã
function MyComponent() {
const [didMount, setDidMount] = useState(false);
useEffect(() => {
setDidMount(true);
}, []);
if (didMount) {
// ... return client-only JSX ...
} else {
// ... return initial JSX ...
}
}
ã¢ããªãããŒããããŠããéããŠãŒã¶ã¯åæã¬ã³ããŒã®åºåã衚瀺ããŸããããŒããšãã€ãã¬ãŒã·ã§ã³ãå®äºãããããšãã§ã¯ããå®è¡ãããdidMount
ã true
ã«ã»ãããããåã¬ã³ããŒãããªã¬ãããŸããããã«ãããã¯ã©ã€ã¢ã³ãå°çšã®ã¬ã³ããŒåºåã«åãæ¿ãããŸãããšãã§ã¯ãã¯ãµãŒãäžã§ã¯å®è¡ãããªããããååãµãŒãã¬ã³ããŒæã«ã¯ didMount
㯠false
ã®ãŸãŸã«ãªããŸãã
ãã®ãã¿ãŒã³ã¯ç¯åºŠãæã£ãŠäœ¿çšããŠãã ãããé ãæ¥ç¶ã®ãŠãŒã¶ã¯åæã³ã³ãã³ããããªãé·ãæéãå Žåã«ãã£ãŠã¯æ°ç§ä»¥äžè¡šç€ºããããšã«ãªããŸãããªã®ã§ã³ã³ããŒãã³ãã®èŠãç®ã«éåæãäžããå€æŽãããªãããã«ããŠãã ãããå€ãã®å ŽåãCSS ã§æ¡ä»¶ä»ãã«ç°ãªããã®ã衚瀺ããããšã§ããã®ãããªããšã¯ããªããŠãããªããŸãã
ãã©ãã«ã·ã¥ãŒãã£ã³ã°
ã³ã³ããŒãã³ãã®ããŠã³ãæã«ãšãã§ã¯ãã 2 åå®è¡ããã
Strict Mode ããªã³ã®å Žåãéçºæã« React ã¯å®éã®ã»ããã¢ããã®åã«ãã»ããã¢ãããšã¯ãªãŒã³ã¢ãããããäžåºŠå®è¡ããŸãã
ããã¯ããšãã§ã¯ãã®ããžãã¯ãæ£ããå®è£ ãããŠããããšã確èªããããã®ã¹ãã¬ã¹ãã¹ãã§ãããããç®ã«èŠããåé¡ãåŒãèµ·ããå Žåãã¯ãªãŒã³ã¢ããé¢æ°ã«äžéšã®ããžãã¯ãæ¬ ããŠããŸããã¯ãªãŒã³ã¢ããé¢æ°ã¯ãã»ããã¢ããé¢æ°ãè¡ã£ãŠããããšãåæ¢ãªããå ã«æ»ãå¿ èŠããããŸããåºæ¬ååã¯ããŠãŒã¶ãã»ããã¢ãããäžåºŠåŒã°ããå ŽåïŒæ¬çªç°å¢ã®å ŽåïŒãšãã»ããã¢ãã â ã¯ãªãŒã³ã¢ãã â ã»ããã¢ãããšããã·ãŒã±ã³ã¹ã§åŒã°ããå ŽåïŒéçºç°å¢ã®å ŽåïŒã§ãéããèŠåããããŠã¯ãããªãããšããããšã§ãã
ã©ã®ããã«ãã°ãèŠã€ããã®ã«åœ¹ç«ã€ã ãšãããžãã¯ãä¿®æ£ããæ¹æ³ ã«ã€ããŠè©³ããèªãã
ãšãã§ã¯ããåã¬ã³ããŒããšã«å®è¡ããã
ãŸããäŸåé åã®æå®ãå¿ããŠããªãã確èªããŠãã ããã
useEffect(() => {
// ...
}); // ð© No dependency array: re-runs after every render!
äŸåé åãæå®ããŠããã«ããããããããšãã§ã¯ããã«ãŒãã§åå®è¡ãããå Žåãããã¯åã¬ã³ããŒããšã«äŸåããå€ã®ã©ãããå€ãã£ãŠããããã§ãã
ãã®åé¡ã¯ãæåã§äŸåããå€ãã³ã³ãœãŒã«ã«ãã°åºåããããšã§ãããã°ã§ããŸãã
useEffect(() => {
// ..
}, [serverUrl, roomId]);
console.log([serverUrl, roomId]);
次ã«ãã³ã³ãœãŒã«äžã®ç°ãªãåã¬ã³ããŒãã衚瀺ãããé
åãå³ã¯ãªãã¯ãããããã㧠âStore as a global variableâ ãéžæããŸããæåã®ãã®ã temp1
ãšããŠä¿åããã2 çªç®ã®ãã®ã temp2
ãšããŠä¿åããããšãããšã以äžã®ããã«ãã©ãŠã¶ã®ã³ã³ãœãŒã«ã䜿ã£ãŠãäž¡æ¹ã®é
åã§ããããã®å€ãåããã©ããã確èªã§ããŸãã
Object.is(temp1[0], temp2[0]); // Is the first dependency the same between the arrays?
Object.is(temp1[1], temp2[1]); // Is the second dependency the same between the arrays?
Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...
åã¬ã³ããŒããšã«å€ã®å€ããäŸåå€ãèŠã€ãã£ãå Žåãéåžžã¯æ¬¡ã®æ¹æ³ã®ããããã§ä¿®æ£ã§ããŸãã
- ãšãã§ã¯ãããã®ååã® state ã«åºã¥ã state ã®æŽæ°
- ãªããžã§ã¯ãåã®äžèŠãªäŸåå€ãåé€ãã
- é¢æ°åã®äžèŠãªäŸåå€ãåé€ãã
- ãšãã§ã¯ãããææ°ã® props ãš state ãèªã¿åã
æåŸã®æ段ãšããŠãäžèšã®æ¹æ³ãããŸããããªãã£ãå Žåããã®å€ãäœã£ãŠãããšããã useMemo
ãŸãã¯ïŒé¢æ°ã®å ŽåïŒuseCallback
ã§ã©ããããŠãã ããã
ãšãã§ã¯ããç¡éã«ãŒãã§åå®è¡ããç¶ãã
ãšãã§ã¯ããç¡éã«ãŒãã§å®è¡ãããå Žåã以äžã® 2 ã€ã®æ¡ä»¶ãæç«ããŠããã¯ãã§ãã
- ãšãã§ã¯ããäœããã® state ãæŽæ°ããŠããã
- ãã® state æŽæ°ã«ããåã¬ã³ããŒãçºçããããã«ãããšãã§ã¯ãã®äŸåé åãå€æŽãããŠããã
åé¡ãä¿®æ£ããåã«ããšãã§ã¯ããå€éšã·ã¹ãã ïŒDOMããããã¯ãŒã¯ããµãŒãããŒãã£ã®ãŠã£ãžã§ãããªã©ïŒã«æ¥ç¶ããŠãããã©ããã確èªããŠãã ããããšãã§ã¯ãã state ãèšå®ããå¿ èŠãããçç±ã¯äœã§ããïŒ å€éšã·ã¹ãã ãšåæããããã§ããïŒ ãããšããã¢ããªã±ãŒã·ã§ã³ã®ããŒã¿ãããŒãããã§ç®¡çããããšããŠããã®ã§ããããïŒ
å€éšã·ã¹ãã ããªãå Žåããããããšãã§ã¯ããåé€ããããšã§ããžãã¯ãç°¡ç¥åããããã©ãããæ€èšããŠãã ããã
ããæ¬åœã«å€éšã·ã¹ãã ãšåæããŠããå Žåã¯ããšãã§ã¯ãããã€ãã©ã®ãããªæ¡ä»¶äžã§ state ãæŽæ°ããå¿ èŠããããèããŠã¿ãŠãã ãããäœããã³ã³ããŒãã³ãã®èŠèŠçãªåºåã«åœ±é¿ãäžããå€æŽãããã®ã§ããããïŒ ã¬ã³ããŒã«äœ¿çšãããªãããŒã¿ã管çããå¿ èŠãããå Žåã¯ãrefïŒåã¬ã³ããŒãããªã¬ããªãïŒã®æ¹ãé©åãããããŸããããšãã§ã¯ããå¿ èŠä»¥äžã« state ãæŽæ°ïŒããŠåã¬ã³ããŒãããªã¬ïŒããŠããªãããšã確èªããŠãã ããã
æåŸã«ããšãã§ã¯ããé©åãªã¿ã€ãã³ã°ã§ state ãæŽæ°ããŠãããã®ã®ãããã§ãç¡éã«ãŒããæ®ã£ãŠããå Žåã¯ããã® state ã®æŽæ°ã«ãããšãã§ã¯ãã®äŸåé åã®ã©ãããå€æŽãããŠããããã§ããäŸåé åã®å€æŽããããã°ããæ¹æ³ã確èªããŠãã ããã
ã³ã³ããŒãã³ããã¢ã³ããŠã³ããããŠããªãã®ã«ã¯ãªãŒã³ã¢ããããžãã¯ãå®è¡ããã
ã¯ãªãŒã³ã¢ããé¢æ°ã¯ãã¢ã³ããŠã³ãæã ãã§ãªããäŸåé åãå€æŽãããåŸã®åã¬ã³ããŒåŸã«ãå®è¡ãããŸãããŸããéçºäžã«ã¯ãReact ãã³ã³ããŒãã³ãã®ããŠã³ãçŽåŸã«ãã»ããã¢ãã+ã¯ãªãŒã³ã¢ããã 1 åè¿œå ã§å®è¡ããŸãã
察å¿ããã»ããã¢ããã³ãŒãã®ãªãã¯ãªãŒã³ã¢ããã³ãŒãããæã¡ã®å Žåãéåžžã¯ã³ãŒãã®åé¡ããããŸãã
useEffect(() => {
// ðŽ Avoid: Cleanup logic without corresponding setup logic
return () => {
doSomething();
};
}, []);
ã¯ãªãŒã³ã¢ããããžãã¯ã¯ã»ããã¢ããããžãã¯ãšã察称çãã§ãããã»ããã¢ãããè¡ã£ãããšãåæ¢ãªããå ã«æ»ãå¿ èŠããããŸãã
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [serverUrl, roomId]);
ãšãã§ã¯ãã衚瀺ã«é¢ããããšãè¡ã£ãŠãããå®è¡åã«ã¡ãã€ããèŠããã
ãšãã§ã¯ãããã©ãŠã¶ã®ç»é¢æç»ããããã¯ããå¿
èŠãããå Žåã¯ãuseEffect
ã®ä»£ããã« useLayoutEffect
ã䜿çšããŠãã ããããã ããããã¯ã»ãšãã©ã®ãšãã§ã¯ãã«ã¯å¿
èŠãªããšããããšã«æ³šæããŠãã ãããããã¯ããã©ãŠã¶æç»ã®åã«ãšãã§ã¯ããå®è¡ããããšãéèŠãªå Žåã«ã®ã¿å¿
èŠã§ããäŸãã°ããŠãŒã¶ãããŒã«ããããèŠãåã«ãããŒã«ãããã®ãµã€ãºã枬å®ããŠé
眮ããããã«äœ¿çšããŸãã