๐ React Hooks๋?
React ์์ ๊ธฐ์กด์ ์ฌ์ฉํ๋ Class๋ฅผ ์ด์ฉํ ์ฝ๋๋ฅผ ์์ฑํ ํ์ ์์ด,
state์, ์ฌ๋ฌ React ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋๋ก ๋ง๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
React Hook ๊ฐ๋ฐ ๊ณผ์
1. ํด๋์ค ์ปดํฌ๋ํธ ์ฌ์ฉ
-- 2019๋ 2์ ๋ฐ์ดํฐ ์บ์ ๊ฐ๋ฐ --
2. ํจ์ ์ปดํฌ๋ํธ์, ๋ฆฌ์กํธ ํ ์ฌ์ฉ
( ๋ฆฌ์กํธ ํ ์, ํจ์ ์ปดํฌ๋ํธ์์๋ง ์ฌ์ฉ๊ฐ๋ฅํ๋ค )
ํจ์ ์ปดํฌ๋ํธ๊ฐ ์ด๋ค ๊ฐ์ ์ ์งํ ์ ์๋๋ก, '์บ์'๋ฅผ ๋ง๋ค์๋ค.
์ด ์บ์๋ฅผ ์ด์ฉํ๊ณ ์ ๋ง๋ ์ฌ๋ฌ๊ฐ์ API๋ฅผ '๋ฆฌ์กํธ ํ ' ํจ์๋ผ๊ณ ๋ถ๋ฅธ๋ค.
React Hook์ ํ์์ฑ
ํจ์ ์ปดํฌ๋ํธ๋ ํด๋์ค ์ปดํฌ๋ํธ์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ค.
ํจ์ ์ปดํฌ๋ํธ๋ ํด๋์ค ์ปดํฌ๋ํธ์ ๋ค๋ฅด๊ฒ, ๋ชจ๋๋ก ํ์ฉํ๊ธฐ๊ฐ ์ฌ์ฐ๋ฏ๋ก ( why? )
์๋ก์ ์ฅ์ ์ ์ ๋ถ๋ค ๊ฐ์ง๊ณ ์๋ค.
๐ React Hooks ์ฌ์ฉ๊ท์น
๊ฐ์ Hook์ ์ฌ๋ฌ๋ฒ ํธ์ถํ ์ ์๋ค.
export default function App(){
const [value1, setValue1] = useState()
const [value2, setValue2] = useState()
return {
<div>
<div>{value1}</div>
<div>{value2}</div>
</div>
}
}
ํจ์ ์ปดํฌ๋ํธ ๋ชธํต์ด์๋, ๋ชธํต ์ ๋ณตํฉ ์คํ๋ฌธ์ {}์์๋ ์ฌ์ฉํ ์ ์๋ค.
javascript์ block scope๋, block ์ธ์์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ( ์ง์ญ๋ณ์์ด๊ธฐ ๋๋ฌธ์ )
export default function App(){
return {
<div>
// ๋ถ๊ฐ๋ฅ
<div>{const [value, setvalue] = useState()}</div>
</div>
}
}
๋น๋๊ธฐ ํจ์(async ํค์๋๊ฐ ๋ถ์ ํจ์)๋ ์ฝ๋ฐฑํจ์๋ก ์ฌ์ฉํ ์ ์๋ค.
export default function App(){
// useEffect Hook ๋ด๋ถ์, ๋น๋๊ธฐ ํจ์๊ฐ ๋ค์ด๊ฐ๋ฏ๋ก ์๋ฌ ๋ฐ์
useEffect(async () => {
await Promise.resolve(1)
}, [])
return {
<div>
<div>Test</div>
</div>
}
}
๐ React์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ๋ Hooks
1. useState
์ปดํฌ๋ํธ์ state(์ํ)๋ฅผ ๊ด๋ฆฌ ํ ์ ์๋ค.
์ํ์ ๋ฐ๋ผ, ๋ค๋ฅธ ํ๋ฉด ์ถ๋ ฅ
2. useEffect
๋ ๋๋ง ์ดํ์ ์คํํ ์ฝ๋๋ฅผ ๋ง๋ค์ ์๋ค.
์ด๋ค ๋ณ์๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค(์์กด์ฑ), ํน์ ๊ธฐ๋ฅ์ด ์๋ํ๋๋ก ํ ์ ์๋ค.
3. useContext
๋ถ๋ชจ์ปดํฌ๋ํธ์ ์์์ปดํฌ๋ํธ ๊ฐ์ ๋ณ์์ ํจ์๋ฅผ ์ ์ญ์ ์ผ๋ก ์ ์ํ ์ ์๋ค.
4. useReducer
state(์ํ) ์ ๋ฐ์ดํธ ๋ก์ง์, reducer ํจ์์ ๋ฐ๋ก ๋ถ๋ฆฌ ํ ์ ์๋ค.
5. useRef
์ปดํฌ๋ํธ๋ HTML ์์๋ฅผ ๋ํผ๋ฐ์ค๋ก ๊ด๋ฆฌํ ์ ์๋ค.
6. forwardRef
useRef๋ก ๋ง๋ ๋ํผ๋ฐ์ค๋ฅผ ์์ ์ปดํฌ๋ํธ๋ก ์ ๋ฌํ ์ ์๋ค.
7. useImperativeHandle
useRef๋ก ๋ง๋ ๋ํผ๋ฐ์ค์ ์ํ์ ๋ฐ๋ผ, ์คํํ ํจ์๋ฅผ ์ ์ ํ ์ ์๋ค.
8. useMemo, useCallback
์์กด์ฑ ๋ฐฐ์ด์ ์ ํ ๊ฐ์ด ๋ณํ ๋๋ง ๊ฐ,ํจ์๋ฅผ ๋ค์ ์ ์ํ ์ ์๋ค. ( ์ฌ๋๋๋ง์ ์ ์ ์ํจ )
8. useLayoutEffect
๋ชจ๋ DOM ๋ณ๊ฒฝ ํ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๊ทธ๋ฆฌ๊ธฐ(render)์ ์ ์คํ๋๋ ๊ธฐ๋ฅ์ ์ ํ ์ ์๋ค.
9. useDebugValue
์ฌ์ฉ์ ์ ์ Hook์ ๋๋ฒ๊น ์ ๋์์ค๋ค.
๐ useState ์ฌ์ฉ๋ฒ
state๋?
React์์ ์ฌ์ฉ์์ ๋ฐ์์ ๋ฐ๋ผ, ํ๋ฉด์ ๋ฐ๊ฟ์ฃผ๊ธฐ(๋ ๋๋ง) ์ํด ์ฌ์ฉ๋๋ ํธ๋ฆฌ๊ฑฐ์ญํ ์ ํ๋ ๋ณ์
React๊ฐ state๋ฅผ ๊ฐ์ํ๊ณ , ๋ฐ๋ ์ ๋ณด์ ๋ฐ๋ฅธ ํ๋ฉด์ ํ์ํด์ค๋ค.
( state์ setStateํจ์์ ๋ฐํ๊ฐ์ ๋น๊ต )
state ๋ง๋ค๊ธฐ ( useState ์ฌ์ฉ )
// React์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ด์ฅ๋์ด ์๋ useState ํ
์ ์ฌ์ฉํ๋ฉด, state๋ฅผ ๋ง๋ค ์ ์๋ค.
import { useState } from "react";
// const [state, state๋ณ๊ฒฝํจ์] = useState(๊ธฐ๋ณธ state๊ฐ);
const [isLoggedIn, setIsLoggedIn] = useState(false);
state ๋ณ๊ฒฝํ๊ธฐ ( ์ฌ์ฉ์ ๋ฐ์์ ๋ฐ๋ฅธ ๋ค๋ฅธ ํ๋ฉด ๋ณด์ฌ์ฃผ๊ธฐ )
// ์ ์ ๋ง๋ "isLoggedIn" state์ ๊ฐ์ true๋ก ๋ณ๊ฒฝํ๋ค.
setIsLoggedIn(true);
// ** useStateํจ์๋ฅผ ์ฌ์ฉํด ๋ง๋ "state ๋ณ๊ฒฝ ํจ์"๋ฅผ ์ฌ์ฉํ์ฌ์ผ ํ๋ค.
state์ ํน์ง
state๋ ์ด๋์์๋ ์ง ์ฌ์ฉ๊ฐ๋ฅํ๋ค.
ํ์ง๋ง ์ปดํฌ๋ํธ๋ ์๊ฐ์ด ์ง๋๊ณ , ์ฑ์ด ์ปค์ง์๋ก ์ ์ ๋ง์์ง๋ฏ๋ก
์ ์ ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง๋ ๋จ์ ์ด ์๋ค?
useEffect์ useLayoutEffect์ ์ฐจ์ด์
useEffect | useLayoutEffect |
๋น๋๊ธฐ ๋ฐฉ์ | ๋๊ธฐ ๋ฐฉ์ ( ๋๋ ๋๊น์ง React๊ฐ ๊ธฐ๋ค๋ ค์ค ) |
๐ useEffect ์ฌ์ฉ๋ฒ
// React์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ด์ฅ๋์ด ์๋ useState์, useEffect ๋ถ๋ฌ์ค๊ธฐ
import { setState, useEffect } from "react";
...
function App() {
const [data, changeData] = setState(false)
// useEffect(์คํํ ํจ์, ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ ๋ณ์)
useEffect(() => {
if (data.me === null) {
console.log("Data changed!")
}
return () => console.log("์ปดํฌ๋ํธ ํ๊ดด, ์ธ๋ง์ดํธ ๋จ")
}, [data]);
// data๋ณ์๊ฐ ๋ฐ๋๋๋ง๋ค, react๊ฐ ์ด๋ฅผ ๊ฐ์งํด, ์ฝ์์ฐฝ์ "Data changed!" ์ถ๋ ฅ
return (
<div>
<button value="์ ์ฉ" onClick={changeData(!data)} />
</div>
)
}
export default App;
๐ useLayoutEffect ์ฌ์ฉ๋ฒ
// React์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ด์ฅ๋์ด ์๋ useState์, useEffect ๋ถ๋ฌ์ค๊ธฐ
import { setState, useLayoutEffect } from "react";
...
function App() {
const [data, changeData] = setState(false)
// useLayoutEffect(์คํํ ํจ์, ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ ๋ณ์)
useLayoutEffect(() => {
if (data.me === null) {
console.log("Data changed!")
}
return () => console.log("Layout ์ฌ๋ผ์ง")
}, [data]);
// data๋ณ์๊ฐ ๋ฐ๋๋๋ง๋ค, react๊ฐ ์ด๋ฅผ ๊ฐ์งํด, ์ฝ์์ฐฝ์ "Data changed!" ์ถ๋ ฅ
return (
<div>
<button value="์ ์ฉ" onClick={changeData(!data)} />
</div>
)
}
export default App;
๐ useContext ์ฌ์ฉ๋ฒ
์๋ก์ด context ๋ง๋ค๊ธฐ
// newContext.js
import { createContext } from "react" // createContext ํจ์ ๋ถ๋ฌ์ค๊ธฐ
// context์์ homeText๋ ๋ณ์๋ฅผ ๋ง๋ค๊ณ , ๊ณต๋ฐฑ("") ๋ฌธ์๋ฅผ ์ ์ฅํ๋ค.
const newContext = createContext({
homeText: "",
})
context๋ฅผ ์ฌ์ฉํ ๋ถ๋ถ ์ ํํ๊ธฐ, ์๋ก์ด ์ ๋ณด ์ ์ฅํ๊ธฐ
// App.js
import React from "react";
import { View } from "react-native";
import Home from "./Home"; // ์์ ์ปดํฌ๋ํธ ๋ถ๋ฌ์ค๊ธฐ
import { newContext } from "./newContext"; // context ๋ถ๋ฌ์ค๊ธฐ
export default function App() {
// context์ ์ ์ฅํ ์ ๋ณด๋ฅผ ์
๋ ฅํ๋ค.
const homeText = "is Worked!"
// NewContext.Provider๋ก ์ฐ๋ฆฌ๊ฐ ๋ง๋ context๋ฅผ ์ฌ์ฉํ ๋ถ๋ถ์ ๊ฐ์ธ์ค๋ค.
return (
<newContext.Provider value={{ homeText }}>
<View>
<Home />
</View>
</newContext.Provider>
);
}
context ์ฌ์ฉํ๊ธฐ
// Home.js
import React from "react";
import { Text, View } from "react-native";
import { useContext } from "react";
import { newContext } from "../newContext";
export default function Home() {
// useContext hook ์ฌ์ฉํด์, newContext์ ์ ์ฅ๋ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
const { homeText } = useContext(newContext);
// ๋ถ๋ฌ์จ ์ ๋ณด ์ฌ์ฉํ๊ธฐ!!
return (
<View>
<Text>{homeText}<Text>
</View>
);
}
context ์ฌ์ฉ์ ์ข์์
React์์ context ์์ด ๋ณ์๋ ํจ์๋ฅผ ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ก ์ ๋ฌํ๋ ค๋ฉด
๋ถ๋ชจ์์๊ฐ์๋ง ์ ๋ฌ์ด ๊ฐ๋ฅํ๋ฏ๋ก,
์ปดํฌ๋ํธ๊ฐ ๋ง์์ง์๋ก ๋ถํ์ํ ์ปดํฌ๋ํธ๋ฅผ ๋ง์ด ๊ฑฐ์ณ์ผํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค! ( A -> B -> C -> D )
context๋ฅผ ์ด์ฉํ๋ฉด, ์ค๊ฐ๊ณผ์ ์ ์ฌ์น๊ณ ์งํต์ผ๋ก ์ ๋ฌํ ์ ์๋ค! ( A -> D )
context ์ฌ์ฉ์ ์ ์์
์ ๋ฌํ๊ณ ์ํ๋ ์ปดํฌ๋ํธ์ context๋ฅผ ๋ง๋ค๋ฉด, ๋ถํ์ํ ํธ์ถ์ด ์ถ๊ฐ๋ ์ ์์ผ๋ฏ๋ก,
context ์ ์ฉ ํ์ผ์ ๋ง๋ค์ด์ผ ํ๋ค.
์์ ์กฐ๊ฑด )
์ปดํฌ๋ํธ : A, B, C, D ( A๊ฐ ์ต์์ ์ปดํฌ๋ํธ )
์ ๋ฌ : A -> D
A ์ปดํฌ๋ํธ์ context ์์ฑ
D ์ปดํฌ๋ํธ์์ context ๋ถ๋ฌ์ด
์คํ ๊ณผ์ )
1. A๊ฐ ๋ ๋๋ง๋๋ฉฐ, B, C, D๋ฅผ ์ฐจ๋ก๋ก ๋ถ๋ฌ์ด
2. D์์ context๋ฅผ ๊ฐ์ ธ์ค๊ธฐ์ํด A๋ฅผ ๋ค์๋ถ๋ฌ์ด
3. A๋ฅผ ๋ค์ ๋ถ๋ฌ์ค๋ฉด์, ๋ถํ์ํ ์ค๋ณต์ด ๋ฐ์ํจ
๐ useMemo ์ฌ์ฉ๋ฒ
Memoization : ๊ณผ๊ฑฐ์ ๊ณ์ฐํ ๊ฐ์ ๋ฐ๋ณตํด์ ์ฌ์ฉํ ๋, ๊ทธ ๊ฐ์ ์บ์์ ์ ์ฅํ๋ ๊ฒ
- ์ฌ๊ทํจ์์ ์ฌ์ฉํ๋ฉด, ๋ถํ์ํ ๋ฐ๋ณต ์ํ์ ๋ํญ ์ค์ผ ์ ์๋ค.
- ์์กด์ฑ์ ๊ฐ์ง๋ฏ๋ก, ์ฒซ๋ ๋๋ง์์๋ง ์ ์ฅํ ๋ณ์๋ฅผ ์ค์ ํ ์ ์๋ค.
export default function App(){
const data = useMemo(()=> "data",[]);
// ๋ฐ์ดํฐ ๋ณ์๋ ์์กด์ฑ ๋ฐฐ์ด []์๋ฐ๋ผ ์ ์ธ๋๋ค. ( []์ฌ์ฉ์, ์ฒซ ๋ ๋๋ง ์์ 1๋ฒ๋ง ์ ์ธ )
return <></>
}
๐ useCallback ์ฌ์ฉ๋ฒ
useMemo์ ํจ์๋ฒ์ . ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์ฉ๋๋ ํจ์๋ฅผ ์บ์์ ์ ์ฅํ ์ ์๋ค.
export default function App(){
const avatarPressed = useCallback(() => Alert.alert('avatar pressed.'), []);
return <></>
}
โ
๐ useRef ์ฌ์ฉ๋ฒ
HTML์์(ํ๊ทธ)๋ ์ปดํฌ๋ํธ์ ๋ฉ๋ชจ๋ฆฌ์ฃผ์๋ฅผ ๊ฐ์ ธ์, ๊ฐ์ฒด(๋ ํผ๋ฐ์ค) ํ์์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ค.
- current ์์ฑ์ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
- current ๊ฐ์ด ๋ฐ๋์ด๋, ์ฌ๋ ๋๋ง ๋์ง ์๋๋ค.
- ์ฌ๋ ๋๋ง์์๋, current ๊ฐ์ ์์ด์ง์ง ์๋๋ค.
export default App(){
// ๊ดํธ()์์ ์ด๊ธฐ๊ฐ ์
๋ ฅ
const viewRef = useRef(null)
// viewRef ๊ฐ์ฒด์ ์๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
function testFunc(){
viewRef.current?.๋ฉ์๋()
}
/// viewRef์์์, ํด๋น ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ์ ๋ฌ
return <View ref={viewRef}>
<Text>Test</Text>
</View>
}
๐ forwardRef ์ฌ์ฉ๋ฒ
๋ถ๋ชจ ์ปดํฌ๋ํธ์, ์์ ์ปดํฌ๋ํธ๊ฐ [ํจ์ํ ์ปดํฌ๋ํธ]๋ก ์ ์ ๋์์๋,
๋ถ๋ชจ ์ปดํฌ๋ํธ์์, ์์ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ฒด ํ์์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ค.
// ์์ ์ปดํฌ๋ํธ
import {forwardRef} from 'react'
// ๋ถ๋ชจ ์ปดํฌ๋ํธ์ ref๋ฅผ ์ธ์๋ก ๋ฐ์์ฌ ์ ์๋ค.
const _TextInput = (
props,
ref
) => {
// ์์ ์ปดํฌ๋ํธ์ ref์ useRef()๊ฐ์ฒด ์ ๋ฌ
return (
<View>
<Text>Hello</Text>
<TextInput
ref={ref}
{...props}
/>
</View>
);
};
// forwardRef()์ผ๋ก ๊ฐ์ธ์ฃผ๊ธฐ
export const MyTextInput = forwardRef(_TextInput);
// ๋ถ๋ชจ ์ปดํฌ๋ํธ
import {useRef} from 'react'
const Parent = () => {
const testRef = useRef(null);
const setFocus = () => testRef.current?.focus();
// ์์ ์ปดํฌ๋ํธ์๊ฒ ref ์ ๋ฌ
return <ImperativeTextInput ref={testRef} />
};
๐ useImperativehandle ์ฌ์ฉ๋ฒ
useRef์ผ๋ก ๋ง๋ ์ปดํฌ๋ํธ ๊ฐ์ฒด(๋ ํผ๋ฐ์ค)์์, ์ปค์คํ ๋ฉ์๋(ํจ์)๋ฅผ ๋ง๋ค ์ ์๋ค.
import {useRef, useImperativeHandle} from 'react'
const ImperativeTextInput = (props, ref) => {
const textInputRef = useRef<TextInput | null>(null);
// ref์ ์ ๋ฌ๋ฐ์, ๋ฉ์๋๋ฅผ ๋ง๋ค์ด์ค๋ค. ( ๋ค๋ฅธ ref ํธ์ถ ๊ฐ๋ฅ )
useImperativeHandle(
ref,
() => ({
focus() {
textInputRef.current?.focus();
},
dismiss() {
Keyboard.dismiss();
},
}),
[],
);
return <TextInput ref={textInputRef} {...props} />;
};
export default forwardRef(ImperativeTextInput);
dfd
useImperativeHandle
๐ useReducer ์ฌ์ฉ๋ฒ ( Redux ๊ฐ๋ )
์ฌ๋ฌ๊ฐ์ ์ํ๋ฅผ ํตํฉํด ๊ด๋ฆฌํ๋ค.
state : ์ํ
action : ๋ณํ๋ด์ฉ ๊ฐ์ฒด
reducer : state์ action ์ธ์๋ก ๋ฐ์, ๋ค์ ์ํ ๋ฐํํ๋ ํจ์
dispatch : action์ ๋ฐํํ๋ ํจ์
ํ์์ฑ
useState๋ฅผ ์ฌ๋ฌ๋ฒ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ ์ฉํ๋ค
์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ก์ง์, ์ปดํฌ๋ํธ ๋ฐ์ ์์ฑ ๊ฐ๋ฅ
dispatch๋ผ๋ ํจ์๋ก, ์ํ ํตํฉ ๊ด๋ฆฌ -> Context์ ํจ๊ป ์ฌ์ฉํ๋ฉด ์ ์ฉ?
------------- ์ถํ ์ ๋ฐ์ดํธ ----------------
// ๋์์ ์ฌ๋ฌ ์ํ๊ฐ ์
๋ฐ์ดํธ
const onPress = () => {
setMode('hype');
setText('We are Hyped!');
setRed(true);
}
// dispatch์๊ฒ ์ธ์๋ฅผ ์ ๋ฌ๋ฐ์
function reducer(state, action){
// state์ ์ด์ ์ํ๊ฐ ๋ค์ด์์
// action์ {ํค:๊ฐ, ...} ํ์์ ๊ฐ์ฒด(action)๊ฐ ๋ค์ด์์
switch (action.type) {
case 'hype':
// ์ํ๊ฐ ๋ณํ
return {text: action.text, red: true};
case 'carm':
return {...state, red: false};
default
throw new Error('action type์ด ์์ต๋๋ค.');
}
}
function Sence(){
// 1๋ฒ์งธ : reducer ํจ์, 2๋ฒ์งธ : ์ด๊ธฐ ์ํ๊ฐ
const [state, dispatch] = useReducer(reducer, initialState);
// dispatch ํจ์์ {ํค:๊ฐ, ...} ํ์์ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ
const onChange = () => dispatch({type: 'hype', text: 'We are Hyped!'});
const onDecrease = () => dispatch({type: 'carm'});
...
}
cache
React.js๋ ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ ์ญ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก,
cache ๊ฐ์ฒด ์์, key : value ํ์์ผ๋ก ์ ์ฅํ๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
// ์ ์ญ์ ์ธ ์บ์ ์์ฑ
const cache: Record<string, any> = {};
export default function createOrUse<T>(key: string, callback: () => T) {
if (!cache[key]) {
cache[key] = callback();
// ํค : ๊ฐ ์ ์ฅ
}
return cache[key];
// ์
๋ ฅํ ํค์ ํด๋นํ๋ ๊ฐ ๋ฐํ
}
์์กด์ฑ
React.js์ ์บ์๋, ์ํฉ์ ๋ฐ๋ผ ์ ๋ฐ์ดํธํ๋๋ก ๋ง๋๋ ์์กด์ฑ ๋ฐฐ์ด์ ๋ง๋ค ์ ์๋ค.
( ๋ฐฐ์ด ์์ ๊ฐ์ด ๋ฐ๋๋๋ง๋ค, ์บ์๋ฅผ ์ ๋ฐ์ดํธ ํ๋ค. )
useEffect(() => {
console.log("dependency")
}, [์์กด์ฑ1, ์์กด์ฑ2 ...])
/*
1. ์์กด์ฑ ๋ณ๊ฒฝ
2. cache๋ด๋ถ์์, ์์กด์ฑ์ ํด๋นํ๋ key ์ฐพ์์ ์
๋ฐ์ดํธ
3. React๊ฐ ์ปดํฌ๋ํธ๋ฅผ ์ฌ๋ ๋๋งํจ
*/
์ฌ๋ฌ๊ฐ์ง React Hooks ๋ผ์ด๋ธ๋ฌ๋ฆฌ
1. react-hook-form
๋ฐ์ํ