[React] Context API

์œ ์•„ํ˜„ยท2023๋…„ 5์›” 2์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
28/28
post-thumbnail

๐ŸŒฑ Intro

์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋Š” Props์„ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ ๋˜๋Š”๋ฐ ํ•ญ์ƒ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๊ฑด state๋ฅผ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•ด ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ์šฐ์ด๋‹ค. ์ฆ‰ ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” Props์„ ํ™œ์šฉํ•ด ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ Props๋ฅผ ๋‚ด๋ ค๋ฐ›๋Š”๋ฐ, ์ƒ์œ„ - ํ•˜์œ„ - ํ•˜์œ„์˜ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ ๋ฐ›๋Š” ๊ฒฝ์šฐ์—๋Š” Props๋ฅผ ๊ณ„์† ์ด์–ด์„œ ๋‚ด๋ ค์ฃผ๋Š” ํ˜•ํƒœ๊ฐ€ ๋œ๋‹ค. ํ•˜์ง€๋งŒ ํ•˜์œ„์˜ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์œ„์—์„œ ํ•˜์œ„๋กœ Props๋ฅผ ๋‚ด๋ ค ์ฃผ๊ณ  ํ•˜์œ„์—์„œ ํ•˜์œ„์˜ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— Props๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š”๋ฐ ์ด ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์•ฑ์ด ํฌ๋‹ค๋ฉด ์ ์  Props์˜ ๋“œ๋ฆด๋ง์ด ๊นŠ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค...?


๋‘๋งํ•˜๋ฉด ์ž”์†Œ๋ฆฌ...

Context API๋ฅผ ์ด์šฉํ•ด๋ณด์ž...

๐Ÿ“Œ Context API

  • ๋ฆฌ์•กํŠธ ๋‚ด์žฅ ๊ธฐ๋Šฅ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ Props๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ์ฃผ๋ฉฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค€๋‹ค.
  • props drilling ๋Œ€์‹  ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์— ์œ ์šฉํ•˜๊ณ , provider ๋‚ด๋ถ€์—์„œ ์ƒํƒœ ๋ณ€๊ฒฝ์ด ๊ฑฐ์˜ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ํ•ด๋‹น ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์šฉ๋„๋กœ ์“ฐ๋Š” ๋ฐ์— ์ ์ ˆํ•˜๋‹ค.

์ด๋ ‡๊ฒŒ ๋ฆฌ์•กํŠธ ๋‚ด๋ถ€์ ์œผ๋กœ stste๋ฅผ ๊ด€๋ฆฌํ•ด ์ฃผ๋Š” Context API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ์•ฑ์˜ ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ์—์„œ๋ผ๋„ ์ง์ ‘ ๋ณ€๊ฒฝํ•ด ์•ฑ์˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์— ์ง์ ‘ ์ „๋‹ฌํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ? ๐Ÿค”

๋‚˜์˜ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ค Tab์ธ์ง€๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ Tab๋ณ„๋กœ ์นดํ…Œ๊ณ ๋ฆฌ์— ๋งž๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ ์ฃผ๊ธฐ ์œ„ํ•ด์„œ Tab์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด context API๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ–ˆ๋‹ค! ์ƒํƒœ ๋ณ€ํ™”๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ํฌ๊ฒŒ ์ผ์–ด๋‚  ๊ฒƒ ๊ฐ™์ง€ ์•Š๊ณ , ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋กœ ์€๊ทผ ๋‚˜๋ˆ„์–ด์ ธ ์žˆ์–ด์„œ props ๋“œ๋ฆด๋ง์ด ์ผ์–ด๋‚ฌ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ปดํฌ๋„ŒํŠธ์— props ์ „๋‹ฌ์„ ํ•˜์ง€ ์•Š์œผ๋ ค๊ณ  ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ƒํƒœ ๊ด€๋ฆฌ๋กœ ๋ฆฌ๋•์Šค๋Š” ์‚ฌ์šฉํ•ด ๋ณด์•˜์ง€๋งŒ... context API๋Š” ์‚ฌ์šฉํ•œ๋‹คํ•œ๋‹ค ํ•˜๊ณ  ํ•œ ๋ฒˆ๋„ ์‚ฌ์šฉํ•œ ์ ์ด ์—†์—ˆ๊ธฐ์— ์ด๋ฒˆ ๊ธฐํšŒ์— ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค!

  1. Context ์ƒ์„ฑ
import React, {
  PropsWithChildren,
  createContext,
  useState,
  useMemo,
} from 'react';
import Tab from '../constants/Tab';

interface TabContextType {
  currentTab: string;
  setCurrentTab: React.Dispatch<React.SetStateAction<string>>;
}

export const TabContext = createContext<TabContextType>({
  currentTab: Tab.All,
  setCurrentTab: () => {},
});

/*
 createContext๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ context๋ฅผ ์ƒ์„ฑํ•œ๋‹ค! ์ธ์ž๋กœ๋Š” ์ดˆ๊ธฐ๊ฐ’์„ ๋„ฃ์–ด ์ฃผ์—ˆ๋‹ค!
 const TabContext = React.createContext() ์™€ ๊ฐ™์ด context๋ฅผ ์ƒ์„ฑํ•ด๋„ ๋œ๋‹ค.

 Context๋ฅผ ์ƒ์„ฑํ•˜๋ฉด Context ์•ˆ์˜ Provider ๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•ด Context์˜ ๊ฐ’์„ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. 
 ๊ทธ ๊ฐ’์€ value๋กœ ์ •ํ•˜์—ฌ ์„ค์ •ํ•œ๋‹ค!
 ์•„๋ž˜์™€ ๊ฐ™์ด TabProvider๋ฅผ ๋งŒ๋“ค์–ด ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ์œ„๋กœ ๊ฐ์‹ธ ์ฃผ๋ฉด ๋œ๋‹ค.
 
 <TabProvider>
	<์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ>
 </TabProvider>
 
*/ 

function TabProvider({ children }: PropsWithChildren<{}>) {
  const [currentTab, setCurrentTab] = useState<string>(Tab.All);

  const value = useMemo(
    () => ({ currentTab, setCurrentTab }),
    [currentTab, setCurrentTab],
  );

  return <TabContext.Provider value={value}>{children}</TabContext.Provider>;
}

export default TabProvider;

๊ทผ๋ฐ ์ด๋ ‡๊ฒŒ context ์ ์ ˆํ•˜๊ฒŒ ์ž˜ ์ƒ์„ฑํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ์˜ค๋ฅ˜ ํˆฌ์„ฑ์ด๊ฐ€ ๋– ์„œ ์™œ ๊ทธ๋Ÿฌ์ง€...? ํ–ˆ๋Š”๋ฐ return์„ jsx๋กœ ๋˜๊ณ  ์žˆ์–ด์„œ ํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ ts๋กœ ํ•ด ๋‘์–ด์„œ ์˜ค๋ฅ˜ ํˆฌ์„ฑ์ด๊ฐ€ ๋˜์—ˆ๋‹ค... ํ™•์žฅ์ž ํ™•์ธ ์ž˜ํ•˜์ž...! ์ฐธ๊ณ 

  1. ์ƒํƒœ ๊ฐ’ ์‚ฌ์šฉ
// ์ƒํƒœ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์šฐ์„  useContext๋ฅผ import ํ•œ๋‹ค.
import { useContext } from 'react';

// ๊ทธ๋ฆฌ๊ณ  createContect๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค์—ˆ๋˜ Context ๋˜ํ•œ import ํ•œ๋‹ค.
import { TabContext } from  '../context/TabContext';


/*
  ์‚ฌ์šฉํ•˜๋ ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด์–ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. 
  ๋‚˜๋Š” ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ
  const value = useContext(TabContext);
  ์™€ ๊ฐ™์ด ํ•˜์—ฌ value.currentTab ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.
*/

const { currentTab } = useContext(TabContext);

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฌด์ง€์„ฑ props๋กœ ๋„˜๊ฒจ ์ฃผ์—ˆ๋˜ ๋ถ€๋ถ„๋„ ๊น”๋”ํ•˜๊ฒŒ ์‚ญ์ œ๊ฐ€ ๋˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์—๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์™€ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด๋ ‡๊ฒŒ ์ข‹์€ context API์—๋„ ๋‹จ์ ์ด ์žˆ์—‡์œผ๋‹ˆ , , ,

๋‹จ์ ...

  • ์ƒํƒœ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด provider๋กœ ๊ฐ์‹ผ ๋ชจ๋“  ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ๋ฆฌ๋ Œ๋”๋ง์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Context API๋ฅผ ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์žฆ์€ ์ƒํƒœ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๊ฒŒ ๋œ๋‹ค๋ฉด ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋„๋ก ๋ฐฉ์–ดํ•ด์•ผ ํ•œ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€