ã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã䜿çšããŠReact Contextã®ããã©ãŒãã³ã¹ãæé©åããŸããå ·äœçãªäŸãšãã¹ããã©ã¯ãã£ã¹ãéããŠãåã¬ã³ããªã³ã°ãæžãããã¢ããªã±ãŒã·ã§ã³ã®å¹çãåäžãããŸãã
React Contextã®æé©åïŒã»ã¬ã¯ã¿ãŒãã¿ãŒã³ãšããã©ãŒãã³ã¹
React Contextã¯ãããããããªãªã³ã°ãªãã§ã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ã管çããã³ã³ããŒãã³ãéã§å ±æããããã®åŒ·åãªã¡ã«ããºã ãæäŸããŸããããããContextã®çŽ æŽãªå®è£ ã¯ãç¹ã«å€§èŠæš¡ã§è€éãªã¢ããªã±ãŒã·ã§ã³ã«ãããŠãããã©ãŒãã³ã¹ã®ããã«ããã¯ãåŒãèµ·ããå¯èœæ§ããããŸããContextã®å€ã倿Žããããã³ã«ããã®Contextã䜿çšãããã¹ãŠã®ã³ã³ããŒãã³ãã¯ãããŒã¿ã®ããäžéšã«ããäŸåããŠããªãå Žåã§ãåã¬ã³ããªã³ã°ãããŸãã
ãã®èšäºã§ã¯ãReact Contextã®ããã©ãŒãã³ã¹ãæé©åããããã®æŠç¥ãšããŠã»ã¬ã¯ã¿ãŒãã¿ãŒã³ãæ·±ãæãäžããŸãããã®ä»çµã¿ãå©ç¹ããããŠäœ¿çšæ³ã瀺ãããã®å®è·µçãªäŸãæ¢ããŸãããŸããé¢é£ããããã©ãŒãã³ã¹ã®èæ ®äºé ãšä»£æ¿ã®æé©åææ³ã«ã€ããŠãè°è«ããŸãã
åé¡ã®çè§£ïŒäžèŠãªåã¬ã³ããªã³ã°
äž»ãªåé¡ã¯ãReactã®Context APIããContextå€ã倿Žããããã³ã«ãããã©ã«ãã§ãã®Contextã䜿çšãããã¹ãŠã®ã³ã³ããŒãã³ãã®åã¬ã³ããªã³ã°ãããªã¬ãŒãããšããäºå®ã«èµ·å ããŸããContextããŠãŒã¶ãŒãããã¡ã€ã«ããŒã¿ãããŒãèšå®ãã¢ããªã±ãŒã·ã§ã³æ§æãå«ã倧ããªãªããžã§ã¯ããä¿æããŠããã·ããªãªãèããŠã¿ãŸãããããŠãŒã¶ãŒãããã¡ã€ã«å ã®åäžã®ããããã£ãæŽæ°ãããšãContextã䜿çšãããã¹ãŠã®ã³ã³ããŒãã³ãããããŒãèšå®ã®ã¿ã«äŸåããŠããå Žåã§ãåã¬ã³ããªã³ã°ãããŸãã
ããã¯ãç¹ã«è€éãªã³ã³ããŒãã³ãéå±€ãé »ç¹ãªContextæŽæ°ãæ±ãå Žåã«ãæ·±å»ãªããã©ãŒãã³ã¹äœäžã«ã€ãªããå¯èœæ§ããããŸããäžèŠãªåã¬ã³ããªã³ã°ã¯è²ŽéãªCPUãµã€ã¯ã«ãç¡é§ã«ãããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ã®åäœãéãããå¯èœæ§ããããŸãã
ã»ã¬ã¯ã¿ãŒãã¿ãŒã³ïŒã¿ãŒã²ãããçµã£ãæŽæ°
ã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã¯ãã³ã³ããŒãã³ããå¿ èŠãšããContextå€ã®ç¹å®ã®éšåã«ã®ã¿ãµãã¹ã¯ã©ã€ãããããšãå¯èœã«ããããšã§ã解決çãæäŸããŸããContextå šäœãæ¶è²»ãã代ããã«ãã³ã³ããŒãã³ãã¯ã»ã¬ã¯ã¿ãŒé¢æ°ã䜿çšããŠé¢é£ããŒã¿ãæœåºããŸããããã«ãããåã¬ã³ããªã³ã°ã®ç¯å²ãçž®å°ãããå®éã«å€æŽãããããŒã¿ã«äŸåããã³ã³ããŒãã³ãã®ã¿ãæŽæ°ãããããã«ãªããŸãã
ä»çµã¿ïŒ
- Contextãããã€ããŒïŒContextãããã€ããŒã¯ã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ãä¿æããŸãã
- ã»ã¬ã¯ã¿ãŒé¢æ°ïŒãããã¯ãContextå€ãå ¥åãšããŠåãåããæŽŸçå€ãè¿ãçŽç²ãªé¢æ°ã§ããContextããç¹å®ã®ããŒã¿éšåãæœåºãããã£ã«ã¿ãŒãšããŠæ©èœããŸãã
- ã³ã³ããŒãã³ãã®æ¶è²»ïŒã³ã³ããŒãã³ãã¯ãã«ã¹ã¿ã ããã¯ïŒãã°ãã°`useContextSelector`ãšåä»ããããŸãïŒã䜿çšããŠãã»ã¬ã¯ã¿ãŒé¢æ°ã®åºåã«ãµãã¹ã¯ã©ã€ãããŸãããã®ããã¯ã¯ãéžæãããããŒã¿ã®å€æŽãæ€åºããå¿ èŠãªå Žåã«ã®ã¿åã¬ã³ããªã³ã°ãããªã¬ãŒãã責任ããããŸãã
ã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã®å®è£
ã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã®å®è£ ã瀺ãåºæ¬çãªäŸã以äžã«ç€ºããŸãã
1. Contextã®äœæ
ãŸããContextãå®çŸ©ããŸãããŠãŒã¶ãŒã®ãããã¡ã€ã«ãšããŒãèšå®ã管çããããã®Contextãæ³åããŠã¿ãŸãããã
import React, { createContext, useState, useContext } from 'react';
const AppContext = createContext({});
const AppProvider = ({ children }) => {
const [user, setUser] = useState({
name: 'John Doe',
email: 'john.doe@example.com',
location: 'New York'
});
const [theme, setTheme] = useState({
primaryColor: '#007bff',
secondaryColor: '#6c757d'
});
const updateUserName = (name) => {
setUser(prevUser => ({ ...prevUser, name }));
};
const updateThemeColor = (primaryColor) => {
setTheme(prevTheme => ({ ...prevTheme, primaryColor }));
};
const value = {
user,
theme,
updateUserName,
updateThemeColor
};
return (
{children}
);
};
export { AppContext, AppProvider };
2. ã»ã¬ã¯ã¿ãŒé¢æ°ã®äœæ
次ã«ãContextããå¿ èŠãªããŒã¿ãæœåºããããã®ã»ã¬ã¯ã¿ãŒé¢æ°ãå®çŸ©ããŸããäŸãã°ïŒ
const selectUserName = (context) => context.user.name;
const selectPrimaryColor = (context) => context.theme.primaryColor;
3. ã«ã¹ã¿ã ããã¯ïŒ`useContextSelector`ïŒã®äœæ
ãããã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã®æ žå¿ã§ãã`useContextSelector`ããã¯ã¯ã»ã¬ã¯ã¿ãŒé¢æ°ãå ¥åãšããŠåãåããéžæãããå€ãè¿ããŸãããŸããContextãžã®ãµãã¹ã¯ãªãã·ã§ã³ã管çããéžæãããå€ã倿Žãããå Žåã«ã®ã¿åã¬ã³ããªã³ã°ãããªã¬ãŒããŸãã
import { useContext, useState, useEffect, useRef } from 'react';
const useContextSelector = (context, selector) => {
const [selected, setSelected] = useState(() => selector(useContext(context)));
const latestSelector = useRef(selector);
const contextValue = useContext(context);
useEffect(() => {
latestSelector.current = selector;
});
useEffect(() => {
const nextSelected = latestSelector.current(contextValue);
if (!Object.is(selected, nextSelected)) {
setSelected(nextSelected);
}
}, [contextValue]);
return selected;
};
export default useContextSelector;
説æïŒ
- `useState`ïŒã»ã¬ã¯ã¿ãŒã«ãã£ãŠè¿ãããåæå€ã§`selected`ãåæåããŸãã
- `useRef`ïŒææ°ã®`selector`颿°ãä¿åããã³ã³ããŒãã³ããåã¬ã³ããªã³ã°ãããŠãææ°ã®ã»ã¬ã¯ã¿ãŒã䜿çšãããããã«ããŸãã
- `useContext`ïŒçŸåšã®ã³ã³ããã¹ãå€ãååŸããŸãã
- `useEffect`ïŒãã®ãšãã§ã¯ãã¯ã`contextValue`ã倿Žããããã³ã«å®è¡ãããŸããå éšã§ã¯ã`latestSelector`ã䜿çšããŠéžæãããå€ãåèšç®ããŸããæ°ããéžæãããå€ãçŸåšã®`selected`å€ãšç°ãªãå ŽåïŒæ·±ãæ¯èŒã«ã¯`Object.is`ã䜿çšïŒã`selected`ç¶æ ãæŽæ°ãããåã¬ã³ããªã³ã°ãããªã¬ãŒãããŸãã
4. ã³ã³ããŒãã³ãã§ã®Contextã®äœ¿çš
ããã§ãã³ã³ããŒãã³ãã¯`useContextSelector`ããã¯ã䜿çšããŠãContextã®ç¹å®ã®éšåã«ãµãã¹ã¯ã©ã€ãã§ããŸãã
import React from 'react';
import { AppContext, AppProvider } from './AppContext';
import useContextSelector from './useContextSelector';
const UserName = () => {
const userName = useContextSelector(AppContext, selectUserName);
return User Name: {userName}
;
};
const ThemeColorDisplay = () => {
const primaryColor = useContextSelector(AppContext, selectPrimaryColor);
return Theme Color: {primaryColor}
;
};
const App = () => {
return (
);
};
export default App;
ãã®äŸã§ã¯ã`UserName`ã¯ãŠãŒã¶ãŒåã倿Žãããå Žåã«ã®ã¿åã¬ã³ããªã³ã°ããã`ThemeColorDisplay`ã¯ãã©ã€ããªã«ã©ãŒã倿Žãããå Žåã«ã®ã¿åã¬ã³ããªã³ã°ãããŸãããŠãŒã¶ãŒã®ã¡ãŒã«ã¢ãã¬ã¹ãå Žæã倿ŽããŠãã`ThemeColorDisplay`ãåã¬ã³ããªã³ã°ãããããšã¯ãªãããã®éãåæ§ã§ãã
ã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã®å©ç¹
- åã¬ã³ããªã³ã°ã®åæžïŒäž»ãªå©ç¹ã¯ãäžèŠãªåã¬ã³ããªã³ã°ãå€§å¹ ã«åæžãããããã©ãŒãã³ã¹ãåäžããããšã§ãã
- ããã©ãŒãã³ã¹ã®åäžïŒåã¬ã³ããªã³ã°ãæå°éã«æããããšã§ãã¢ããªã±ãŒã·ã§ã³ã¯ããå¿çæ§ãé«ããå¹ççã«ãªããŸãã
- ã³ãŒãã®æç¢ºãïŒã»ã¬ã¯ã¿ãŒé¢æ°ã¯ãã³ã³ããŒãã³ãã®ããŒã¿äŸåé¢ä¿ãæç€ºçã«å®çŸ©ããããšã§ãã³ãŒãã®æç¢ºããšä¿å®æ§ãä¿é²ããŸãã
- ãã¹ãå®¹ææ§ïŒã»ã¬ã¯ã¿ãŒé¢æ°ã¯çŽç²ãªé¢æ°ã§ããããããã¹ããæšè«ã容æã§ãã
èæ ®äºé ãšæé©å
1. ã¡ã¢å
ã¡ã¢åã¯ãã»ã¬ã¯ã¿ãŒé¢æ°ã®ããã©ãŒãã³ã¹ãããã«åäžãããããšãã§ããŸããå ¥åContextå€ã倿ŽãããŠããªãå Žåãã»ã¬ã¯ã¿ãŒé¢æ°ã¯ãã£ãã·ã¥ãããçµæãè¿ããäžèŠãªèšç®ãåé¿ã§ããŸããããã¯ãã³ã¹ãã®ãããèšç®ãå®è¡ããè€éãªã»ã¬ã¯ã¿ãŒé¢æ°ã«ãšã£ãŠç¹ã«åœ¹ç«ã¡ãŸãã
`useContextSelector`ã®å®è£ å ã§`useMemo`ããã¯ã䜿çšããŠãéžæãããå€ãã¡ã¢åã§ããŸããããã«ãããContextå€ã倿ŽãããŠãéžæãããå€ãåããŸãŸã§ããå Žåã«ãäžèŠãªåã¬ã³ããªã³ã°ãé²ããã1ã€ã®æé©åã¬ã€ã€ãŒã远å ãããŸããã¡ã¢åã远å ããæŽæ°çã®`useContextSelector`ã以äžã«ç€ºããŸãã
import { useContext, useState, useEffect, useRef, useMemo } from 'react';
const useContextSelector = (context, selector) => {
const latestSelector = useRef(selector);
const contextValue = useContext(context);
useEffect(() => {
latestSelector.current = selector;
}, [selector]);
const selected = useMemo(() => latestSelector.current(contextValue), [contextValue]);
return selected;
};
export default useContextSelector;
2. ãªããžã§ã¯ãã®äžå€æ§
Contextå€ã®äžå€æ§ã確ä¿ããããšã¯ãã»ã¬ã¯ã¿ãŒãã¿ãŒã³ãæ£ããæ©èœããããã«äžå¯æ¬ ã§ããContextå€ãçŽæ¥å€æŽãããå Žåãã»ã¬ã¯ã¿ãŒé¢æ°ã¯å€æŽãæ€åºã§ããã誀ã£ãã¬ã³ããªã³ã°ã«ã€ãªããå¯èœæ§ããããŸããContextå€ãæŽæ°ããéã¯ãåžžã«æ°ãããªããžã§ã¯ããŸãã¯é åãäœæããŠãã ããã
3. ãã£ãŒãæ¯èŒ
`useContextSelector`ããã¯ã¯ãéžæãããå€ãæ¯èŒããããã«`Object.is`ã䜿çšããŸããããã¯ã·ã£ããŒæ¯èŒãå®è¡ããŸããè€éãªãªããžã§ã¯ãã®å Žåã倿Žãæ£ç¢ºã«æ€åºããããã«ãã£ãŒãæ¯èŒé¢æ°ã䜿çšããå¿ èŠããããããããŸããããã ãããã£ãŒãæ¯èŒã¯èšç®ã³ã¹ããé«ããªãå¯èœæ§ããããããæ éã«äœ¿çšããŠãã ããã
4. `Object.is`ã®ä»£æ¿
`Object.is`ãååã§ãªãå ŽåïŒäŸïŒContextã«æ·±ããã¹ãããããªããžã§ã¯ããããå ŽåïŒãä»£æ¿ææ®µãæ€èšããŠãã ããã`lodash`ã®ãããªã©ã€ãã©ãªã¯ãã£ãŒãæ¯èŒã®ããã«`_.isEqual`ãæäŸããŸãããããã©ãŒãã³ã¹ãžã®åœ±é¿ã«æ³šæããŠãã ãããå Žåã«ãã£ãŠã¯ãImmutableããŒã¿æ§é ïŒImmerãªã©ïŒã䜿çšããæ§é å ±æãã¯ããã¯ã圹ç«ã€ããšããããŸãããããã¯å ã®ãªããžã§ã¯ãã倿Žããã«ãã¹ãããããªããžã§ã¯ãã倿Žã§ããå€ãã®å Žå`Object.is`ã§æ¯èŒã§ããããã§ãã
5. ã»ã¬ã¯ã¿ãŒã®ããã®`useCallback`
`selector`颿°èªäœãé©åã«ã¡ã¢åãããŠããªãå ŽåãäžèŠãªåã¬ã³ããªã³ã°ã®åå ãšãªãå¯èœæ§ããããŸããäŸåé¢ä¿ã倿Žãããå Žåã«ã®ã¿åäœæãããããã«ã`selector`颿°ã`useCallback`ã«æž¡ããŠãã ãããããã«ãããã«ã¹ã¿ã ããã¯ãžã®äžèŠãªæŽæ°ãé²ããŸãã
const UserName = () => {
const userName = useContextSelector(AppContext, useCallback(selectUserName, []));
return User Name: {userName}
;
};
6. `use-context-selector`ã®ãããªã©ã€ãã©ãªã®äœ¿çš
`use-context-selector`ã®ãããªã©ã€ãã©ãªã¯ãããã©ãŒãã³ã¹ãæé©åãããã·ã£ããŒæ¯èŒã®ãããªæ©èœãå«ããäºåã«æ§ç¯ããã`useContextSelector`ããã¯ãæäŸããŸãããã®ãããªã©ã€ãã©ãªã䜿çšãããšãã³ãŒããç°¡çŽ åãããšã©ãŒãå°å ¥ãããªã¹ã¯ãæžããããšãã§ããŸãã
import { useContextSelector } from 'use-context-selector';
import { AppContext } from './AppContext';
const UserName = () => {
const userName = useContextSelector(AppContext, selectUserName);
return User Name: {userName}
;
};
ã°ããŒãã«ãªäŸãšãã¹ããã©ã¯ãã£ã¹
ã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã¯ãã°ããŒãã«ãªã¢ããªã±ãŒã·ã§ã³ã«ãããæ§ã ãªãŠãŒã¹ã±ãŒã¹ã«é©çšå¯èœã§ãã
- ããŒã«ã©ã€ãŒãŒã·ã§ã³ïŒè€æ°ã®èšèªããµããŒãããeã³ããŒã¹ãã©ãããã©ãŒã ãæ³åããŠã¿ãŠãã ãããContextã¯çŸåšã®ãã±ãŒã«ãšç¿»èš³ãä¿æã§ããŸããããã¹ãã衚瀺ããã³ã³ããŒãã³ãã¯ãã»ã¬ã¯ã¿ãŒã䜿çšããŠçŸåšã®ãã±ãŒã«ã«é¢é£ããç¿»èš³ãæœåºã§ããŸãã
- ããŒã管çïŒãœãŒã·ã£ã«ã¡ãã£ã¢ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããŠãŒã¶ãŒãããŒããã«ã¹ã¿ãã€ãºã§ããŸããContextã¯ããŒãèšå®ãä¿åã§ããUIèŠçŽ ã衚瀺ããã³ã³ããŒãã³ãã¯ãã»ã¬ã¯ã¿ãŒã䜿çšããŠé¢é£ããããŒãããããã£ïŒäŸïŒè²ããã©ã³ãïŒãæœåºã§ããŸãã
- èªèšŒïŒã°ããŒãã«ãšã³ã¿ãŒãã©ã€ãºã¢ããªã±ãŒã·ã§ã³ã¯ãContextã䜿çšããŠãŠãŒã¶ãŒèªèšŒã¹ããŒã¿ã¹ãšæš©éã管çã§ããŸããã³ã³ããŒãã³ãã¯ãã»ã¬ã¯ã¿ãŒã䜿çšããŠçŸåšã®ãŠãŒã¶ãŒãç¹å®ã®æ©èœã«ã¢ã¯ã»ã¹ã§ãããã©ããã倿ã§ããŸãã
- ããŒã¿ãã§ããã³ã°ã¹ããŒã¿ã¹ïŒå€ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ããŒãç¶æ ã衚瀺ããŸããContextã¯APIåŒã³åºãã®ã¹ããŒã¿ã¹ã管çã§ããã³ã³ããŒãã³ãã¯ç¹å®ã®ãšã³ããã€ã³ãã®ããŒãç¶æ ã«éžæçã«ãµãã¹ã¯ã©ã€ãã§ããŸããäŸãã°ããŠãŒã¶ãŒãããã¡ã€ã«ã衚瀺ããã³ã³ããŒãã³ãã¯ã`GET /user/:id`ãšã³ããã€ã³ãã®ããŒãç¶æ ã«ã®ã¿ãµãã¹ã¯ã©ã€ããããããããŸããã
代æ¿ã®æé©åææ³
ã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã¯åŒ·åãªæé©åææ³ã§ãããå©çšå¯èœãªå¯äžã®ããŒã«ã§ã¯ãããŸããã以äžã®ä»£æ¿æ¡ãæ€èšããŠãã ããã
- `React.memo`ïŒããããã倿ŽãããŠããªãå Žåã«åã¬ã³ããªã³ã°ãé²ãããã«ã颿°ã³ã³ããŒãã³ãã`React.memo`ã§ã©ããããŸããããã¯ããããããçŽæ¥åãåãã³ã³ããŒãã³ãã®æé©åã«åœ¹ç«ã¡ãŸãã
- `PureComponent`ïŒã¯ã©ã¹ã³ã³ããŒãã³ãã«ã¯`PureComponent`ã䜿çšããŠãåã¬ã³ããªã³ã°ã®åã«ãããããšç¶æ ã®ã·ã£ããŒæ¯èŒãå®è¡ããŸãã
- ã³ãŒãåå²ïŒã¢ããªã±ãŒã·ã§ã³ãããªã³ããã³ãã§ããŒãã§ããå°ããªãã£ã³ã¯ã«åå²ããŸããããã«ãããåæããŒãæéãççž®ãããå šäœçãªããã©ãŒãã³ã¹ãåäžããŸãã
- ä»®æ³åïŒå€§éã®ããŒã¿ããªã¹ã衚瀺ããå Žåãä»®æ³åæè¡ã䜿çšããŠè¡šç€ºãããŠããã¢ã€ãã ã®ã¿ãã¬ã³ããªã³ã°ããŸããããã«ãããå€§èŠæš¡ãªããŒã¿ã»ãããæ±ãéã®ããã©ãŒãã³ã¹ãå€§å¹ ã«åäžããŸãã
çµè«
ã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã¯ãäžèŠãªåã¬ã³ããªã³ã°ãæå°éã«æããããšã§ãReact Contextã®ããã©ãŒãã³ã¹ãæé©åããããã®è²Žéãªæè¡ã§ããã³ã³ããŒãã³ããå¿ èŠãšããContextå€ã®ç¹å®ã®éšåã«ã®ã¿ãµãã¹ã¯ã©ã€ãã§ããããã«ããããšã§ãã¢ããªã±ãŒã·ã§ã³ã®å¿çæ§ãšå¹çãåäžããŸããã¡ã¢åãã³ãŒãåå²ãªã©ã®ä»ã®æé©åææ³ãšçµã¿åãããããšã§ãã¹ã ãŒãºãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸãã髿§èœãªReactã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸããã¢ããªã±ãŒã·ã§ã³ã®ç¹å®ã®ããŒãºã«åºã¥ããŠé©åãªæé©åæŠç¥ãéžæããé¢é£ãããã¬ãŒããªããæ éã«æ€èšããããšãå¿ããªãã§ãã ããã
ãã®èšäºã§ã¯ãã»ã¬ã¯ã¿ãŒãã¿ãŒã³ã®å®è£ ãå©ç¹ãèæ ®äºé ãå«ãå æ¬çãªã¬ã€ããæäŸããŸããããã®èšäºã§æŠèª¬ãããŠãããã¹ããã©ã¯ãã£ã¹ã«åŸãããšã§ãReact Contextã®äœ¿çšã广çã«æé©åããã°ããŒãã«ãªèŠèŽè åãã«é«æ§èœãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã