all is well!!
1. React ๋์๋ฐฉ์๊ณผ ๋ค์ํ hook ๋ณธ๋ฌธ
๐ ๋ชฉํ
1. ์ปดํฌ๋ํธ๊ฐ ์ธ์ ๋ฆฌ๋ ๋๋ง ๋๋์ง ์ดํด๋ณด๊ธฐ
2. ๋ค์ํ ํ ์ ์ดํดํ๊ณ ์ฌ์ฉํ๊ธฐ
๐ React์ ๋ ๋๋ง ๋ผ์ดํ ์ฌ์ดํด
๐ฃ 1. Trigger
๋จ์ด ๊ทธ๋๋ก ๋ ๋๋ง์ ์์ํ๊ฒ๋ ๋ฐฉ์์ ๋ฅผ ๋น๊ธฐ๋ ๊ณผ์ .
์ธ์ Trigger๊ฐ ๋ฐ๋๋๋์?
1. ์ฒซ๋ฒ์งธ ๋ ๋๋ง์ด ์ํ๋ ๋
a. ReactDOM.createRoot(..).render()
2. ์ปดํฌ๋ํธ์ state๊ฐ ๋ณ๊ฒฝ๋ ๋
a. ํด๋์ค ์ปดํฌ๋ํธ์ setState ๋ฉ์๋
b. useState, useReducer๋ฑ ์ํ๋ณ๊ฒฝ ํ ์ setter ํจ์ ํธ์ถ.
1. ๋ ๋๋ง Batch ์ฒ๋ฆฌ
Trigger ๊ณผ์ ์์ ์ฌ๋ฌ๊ฐ์ง ์์ ์ ํ๋ฒ์ ๋ฌถ์ด์ ์ํํ๋ Batch ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ค.
function Component() {
const [count, setCount] = useState(0);
const increase = () => {
// trigger ํจ์๊ฐ ๋๋ฒ ํธ์ถ๋์์๋
setCount(count + 1);
setCount(count + 2);
};
// ๋๋ฒ ํธ์ถ ๋ ๊น์?
console.log('rendered');
return (
<>
<div>{count}</div>
<button onClick={increase}>Increase</button>
</>
)
}
์ ๋ต์ ์๋์ค!
์ต์ ํ๋ฅผ ์ํด์ ๋ ๋๋ง์ ๋ง์ง๋ง์ ์ง์ ๋ true ๊ฐ์ด ๋ฐ๋๊น์ง ๋ชจ๋ ์ํ๋ณํ๋ฅผ ์ง์ฐ์คํ์์ผ ํ๋ฒ์ ์ ๋ฐ์ดํธ๋ฅผ ์ํํ๋ค.
๊ทธ๋์ ์ฝ์๋ ํ๋ฒ๋ง ์ฐํ๋ค.
๋น๋๊ธฐ ๋ ๋๋ง๋ ์์ ์๋ Batch ์ฒ๋ฆฌ๊ฐ ๋์ง ์์์ง๋ง Fiber Architecture๊ฐ ๋์ ๋๋ฉด์ ๋น๋๊ธฐ ์ฝ๋ฐฑ์์๋ Batch ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํด์ก๋ค.
๐ฃ 2. Render
์ด๋ค ๋ถ๋ถ์ ์ด๋ป๊ฒ ์ ๋ฐ์ดํธ ํด์ผํ๋์ง ํ์ธํ๋ ๋จ๊ณ
1. Virtual DOM
๋ณดํต JS ์ฐ์ฐ๋ณด๋ค DOM์ฐ์ฐ ๋น์ฉ์ด ๋ ํฌ๊ธฐ๋๋ฌธ์ ์ค์ DOM์ ๊ฑด๋๋๊ฒ ์๋ Virtual DOM(DOM์ ๋ชจ๋ฐฉํ JS ๊ฐ์ฒด)์ผ๋ก ์ฐ์ฐ์ ๋ง์น๊ณ DOM์๋ ๊ฒฐ๊ณผ๋ง ๋ฐ์ํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
React์๋ Virtual DOM์ ๊ตฌํํ๊ธฐ ์ํด์ React Element, Fiber, VDOM ๊ฐ๋ ์ ์ฌ์ฉํ๋ค.
2. React Element
HTML ๊ตฌ์กฐ์ฒด๋ก Virtual DOM์ ์์ฑํ๋ ๊ณผ์ ์ ์ข ๋ ํธํ ๋ฌธ๋ฒ์ผ๋ก ๋ค๋ฃฐ ์ ์๊ฒ JSX ๋ฌธ๋ฒ๊ณผ ์ปดํ์ผ๋ฌ๋ฅผ ์ ๊ณตํ๋ค.
return (
<div>
<div>{count}</div>
<button onClick={increase}>Increase</button>
</div>
)
์ด๋ ๊ฒ ์์ฑ๋ JSX ๋ฌธ๋ฒ์
return React.createElement(
'div',
null,
React.createElement('div', null, count),
React.createElement('button', { ... }, 'Increase'),
);
์ปดํ์ผ๋ฌ๋ฅผ ํตํด ์ด๋ฐ ์ฝ๋ ํ์์ผ๋ก ๋ณํ๋๋ค.
์ด๋ฐ React Element ๊ฐ์ฒด๋ ๋ถ๋ณ(Immutable)ํ๋ค.
3. Fiber
๋ ๋๋ง์ ์ฌ๋ฌ ์กฐ๊ฐ์ผ๋ก ์ชผ๊ฐ์ DOM ๋ณ๊ฒฝ ์์๋ฅผ ์ฒ๋ฆฌํ๋ ์๊ณ ๋ฆฌ์ฆ.
Fiber๋ก ์ธํด ๋น๋๊ธฐ ๋ ๋๋ง์ ํต์ฌ์ธ ๋ ๋๋ง ์์ ์ ์ค์งํ๊ณ ๋ค์ ์คํํ๋ ๊ฒ์ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
๋ ๋๋ง ๋จ์๋ ์ผ๋ฐ์ ์ผ๋ก ์ปดํฌ๋ํธ ๋จ์๋ก ์ด๋ฃจ์ด์ง๋ค.
child์ sibling์ ์ฐธ์กฐ๊ฐ์ผ๋ก ๋ค์์ผ๋ก ํด์ผํ ๋ ๋๋ง ์์ ์ธ ๋ค์ Fiber์ ๊ฐ๋ฅดํค๋ ๊ทธ๋ํ ๊ตฌ์กฐ๋ก ๋์ด์๋ค.
function Component() {
const [count, setCount] = useState(0);
const increase = () => setCount(count => count + 1);
return (
<div>
<div>{count}</div>
<button onClick={increase}>Increase</button>
</div>
)
}
scheduleWork(fiber, expireTime)
{
// ์์
์ค์ธ props (props๊ฐ ์์)
pendingProps: null,
// Render Phase ๋๋ ๋ค์ Props (props๊ฐ ์์)
memoizedProps: null,
// count 0 ์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊น๋๋ค.
// ์ค์ DOM์ ์ปค๋ฐ๋์ด์ผ ํ๋๋ฐ WORK๋ค์ด ์ค์ผ์ค๋ง๋๋ update์ ๋ํ ์ ๋ณด๋ ํ๋ก ๊ด๋ฆฌ๋ฉ๋๋ค.
memoizedState: {
baseState: { count: 0 },
next: null, // hook ์ด ์ถ๊ฐ์ ์ผ๋ก ์คํ๋๋ฉด LinkedIn ๋ฐฉ์์ผ๋ก hook ์ ๋ณด๊ฐ ๋ด๊น๋๋ค.
},
...
}
์์ฑ๋ Fiber์ DOM์ ๋ฐ์๋๊ธฐ ์ํด์ ์ค์ผ์ค๋ง ๋๋ค.
4. React Virtual DOM
๋ณ๊ฒฝ์ฌํญ์ ํ์ธํ๊ธฐ ์ํ Fiber ๋ ธ๋์ ํธ๋ฆฌ ์๋ฃ๊ตฌ์กฐ.
virtual dom์๋ ํ์ฌ ์ํ์ ๋ค์ ์ํ๋ฅผ ๋น๊ตํ๊ธฐ ์ํด์ ๋๊ฐ์ ํธ๋ฆฌ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
current tree๋ ํ์ฌ ์ํ์ ํธ๋ฆฌ, workInProgress๋ ํ์ฌ ์์ ์ผ๋ก ์ธํด ๋ฐ๋๋ ํธ๋ฆฌ๋ค.
(์ฝ๊ฒ current tree์ ์ฐธ์กฐ์ฃผ์๋ฅผ working tree์ ๋ฎ์ด์์์ ์ ๋ฐ์ดํธ ํ๋๊ฒ์ผ๋ก ์ดํดํ๋ค.)
๋๋ ์ด๋๊น์ง virtual dom์ผ๋ก ์ธํด ๋ก๋ฉ ์๋๊ฐ ๋น ๋ฅด๋ค๊ณ ์๊ณ ์๋ ์ํ์๋ค.
๊ทธ๋์ virtual dom์ด react์ ์์ ๊ผฝ๋ ์ฅ์ ์ด๋ผ๊ณ ๋ง ์๊ณ ์์๋ค.
ํ์ง๋ง ๋จ์ ๋ ์กด์ฌํ๋ค.
์ฐ์ฐ ๋น์ฉ์ด ํฐ DOM์ ์ง์ ์กฐ์ํ์ง ์์์ ์ฑ๋ฅ์ ๊ฐ์ ํ๋ ์ฉ๋๋ก ์ฐ์์ง๋ง
์ ์ด์ virtual dom์ ๊ด๋ฆฌํ๋๊ฒ ๋ง์ ๋ฉ๋ชจ๋ฆฌ์ CPU ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ๋ค.
(์ด๋ฒ์ ๊ณต๋ถํ๋ฉด์ react ๊ณต์ ๋ฌธ์์์ virtual dom์ด๋ผ๋ ์ฉ์ด๊ฐ ์ ๊ฑฐ๋์๋ค๋ ์์์ ๋ค์๋ค.)
5. ์ฌ์กฐ์ (Reconciliation)๊ณผ diff(Diffing) ์๊ณ ๋ฆฌ์ฆ
์ฌ์กฐ์ : DOM ํธ๋ฆฌ์ ์ ๋ฐ์ดํธ ํด์ผํ๋ ๋ด์ฉ์ ์ด์ ํธ๋ฆฌ์ ๋น๊ตํด ๊ณ์ฐํ๊ณ ํ์ ํ๋ ๊ณผ์
๋ณดํต ๋๊ฐ์ ํธ๋ฆฌ๋ฅผ ๋น๊ตํ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ต์ O(n^3)์ ์ํ๋น์ฉ์ด ๋ฐ์ํ๋ค๊ณ ํ๋ค.
React์์๋ ์์ ์๊ฐ๋ณต์ก๋๋ฅผ ์ค์ด๊ธฐ ์ํด key ๊ฐ์ ์ด์ฉํ Heuristics ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํด์ O(n)๊น์ง ์ค์ด๋๋ฐ ์ฑ๊ณตํ๋ค.
๐ฃ 3. Commit
์ฌ์กฐ์ (Reconciliation) ํ๋ก์ธ์ค์ ๋ง์ง๋ง ๋จ๊ณ๋ก ๋ณํ๋ ๋ถ๋ถ์ DOM์ ๋ฐ์ํ๋ค.
์ด ๋จ๊ณ์์๋ ๋ณดํต ์๋์ ์์ ๋ค์ ์ํํ๋ค.
1. pre-commit phase
๋ณ๊ฒฝ ์ฌํญ์ ํ์ ํ๊ธฐ ์ ์์ ์ค๋น.
์ฃผ๋ก ๋ ์ด์์ ํจ๊ณผ(useLayoutEffect)๊ฐ ์์ฝ๋๋ค.
2. commit phase
DOM ์ ๋ฐ์ดํธ
DOM ์์ฑ ๋ฐ ์คํ์ผ ์ ๋ฐ์ดํธ
Ref ์ ๋ฐ์ดํธ : DOM ์์์ ์ง์ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ผ๋ก ์ด ๋จ๊ณ์์ ์ ๋ฐ์ดํธ ๋๋ค.
๋ ์ด์์ ํจ๊ณผ(useLayoutEffect) ์คํ
3. post-commit phase
Effects ์ ๋ฐ์ดํธ : ์ฌ์ด๋์ดํํธ ํ ์ด ์คํ๋๋ค.
๋น๋๊ธฐ ์์ ์คํ
๐ React์ ์ฌ๋ฌ๊ฐ์ง hook
๐ฃ useState
export default function UseStateTest() {
const [state, setState] = useState({ bar: { count: 1 } });
const increment = () => {
setState((prev)=>({
...prev, // useState๋ ๋ถ๋ณํจ์ ์ง์ผ์ฃผ๋ ํํ๋ก ๊ฐ์ ๋ฐ๊ฟ์ผ ๋ ๋๋ง trigger์ ์กฐ๊ฑด์ด ์ง์ผ์ง๋ค.
bar:{
...prev.bar,
count: prev.bar.count+1
}
}))
}
return (
<div>
count: {state.bar.count}
<button onClick={increment}>์ฆ๊ฐ</button>
</div>
);
}
๐ฃ useMemo
import { useMemo, useState } from "react";
import { repeatBarked, repeatMeow } from "./UseMemoTest.utils.ts";
export default function UseMemoTest() {
const [meowCount, setMeowCount] = useState(1);
const [barkedCount, setBarkedCount] = useState(1);
// useMemo๋ ์์กด์ฑ ๋ฐฐ์ด์ ๊ฐ์ด ์
๋ฐ์ดํธ ๋ ๋๊น์ง ์ด๋ฏธ ๊ณ์ฐ๋ ๊ฐ์ ์บ์ฑํ๋ค.
const meow = useMemo(()=>repeatMeow(meowCount),[meowCount])
const bark = useMemo(()=>repeatBarked(barkedCount),[barkedCount])
return (
<div>
<p data-testid="cat">๊ณ ์์ด "{meow}"</p>
<p data-testid="dog">๊ฐ์์ง "{bark}"</p>
<button data-testid="meow" onClick={() => setMeowCount(n => n + 1)}>์ผ์น</button>
<button data-testid="bark" onClick={() => setBarkedCount(n => n + 1)}>๋ฉ๋ฉ</button>
</div>
);
}
๐ฃ pureComponent
import { memo, useState } from "react";
import { Cat, Dog } from "./PureComponentTest.components.tsx";
// memo๋ ์ปดํฌ๋ํธ๋ฅผ ์บ์ฑํด์ ๋์ผํ props๋ก ์ฌ๋ฌ๋ฒ ๋ ๋๋ง ๋๋๊ฒ์ ๋ฐฉ์งํ๋ค.
// memo๋ฅผ ๊ฑธ์ง์์ผ๋ฉด ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋๋ฉด ์์ ์ปดํฌ๋ํธ๋ ์ ๋ถ ๋ ๋๋ง๋๊ธฐ ๋๋ฌธ์
// memo๋ฅผ ๊ฑธ์ด์ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋์ด๋ ๋์ผํ props์ธ ์์ ์ปดํฌ๋ํธ๋ ๋ ๋๋ง๋์ง ์๊ฒ ๋ง๋๋ค.
const MemoCat = memo(Cat);
const MemoDog = memo(Dog);
export default function PureComponentTest() {
const [meowCount, setMeowCount] = useState(1);
const [barkedCount, setBarkedCount] = useState(1);
return (
<div>
props์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง ๋ ๋๋ง์ด ๋ฐ์
<MemoCat crying={meowCount}/>
<MemoDog crying={barkedCount}/>
<button data-testid="meow" onClick={() => setMeowCount(n => n + 1)}>์ผ์น</button>
<button data-testid="bark" onClick={() => setBarkedCount(n => n + 1)}>๋ฉ๋ฉ</button>
</div>
);
}
๐ฃ useCallback
import { ComponentProps, PropsWithChildren, memo, useCallback, useMemo, useState } from "react";
import { BarkButton, MeowButton } from "./UseCallbackTest.components.tsx";
// pureComponent์ useCallback์ ์ฌ์ฉํด์ ๋ถํ์ํ ๋ ๋๋ง์ ๋ง๋๋ค.
const PureComponent = memo(({ children, ...props }: PropsWithChildren<ComponentProps<'p'>>) => {
return <p {...props}>{children}</p>
})
export default function UseCallbackTest() {
const [meowCount, setMeowCount] = useState(0);
const [barkedCount, setBarkedCount] = useState(0);
const callbackMeowCount = useCallback(
()=>{setMeowCount(n => n + 1)},[setMeowCount]
)
const callbackBarkCount = useCallback(
()=>{setBarkedCount(n => n + 1)},[setBarkedCount]
)
return (
<div>
<PureComponent data-testid='cat'>meowCount {meowCount}</PureComponent>
<PureComponent data-testid='dog'>barkedCount {barkedCount}</PureComponent>
<MeowButton onClick={callbackMeowCount}/>
<BarkButton onClick={callbackBarkCount}/>
</div>
);
}
๐ฃ RequireRefactoring
// useMemo, useCallback ๋ฑ์ ์ฌ์ฉํ์ง ์๊ณ ์ด ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ ํ ์ ์๋ค.
import { ComponentProps, memo, PropsWithChildren } from "react";
type Props = {
countRendering?: () => void;
}
// React๋ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด ์์ ๋น๊ต๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด์ ์ฐธ์กฐ ์ฃผ์๋ฅผ ๋น๊ตํ๋ค.
// ๊ทธ ์ค memo๋ props๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์์ ๋น๊ต๋ฅผ ํ๋ค.
// ๊ทธ๋์ ์ฐธ์กฐ ํ์
์ ๊ฒฝ์ฐ ์ฃผ์๊ฐ ๋ณ๊ฒฝ๋๋ฉด props๊ฐ ๋ณ๊ฒฝ๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผ.
// ๊ทธ๋์ PureComponent๊ฐ memo๋ฅผ ์ผ์ง๋ง ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ๊ฐ์ฒด์ ํจ์๋ก props๋ฅผ ๋๊ฒจ์ฃผ๋ฉด ๊ฐ์ด ๊ฐ์๋ ๋ฆฌ๋ ๋๋ง์ด ๋๋ค.
const PureComponent = memo(({ children, countRendering, ...props }: PropsWithChildren<ComponentProps<'div'> & Props>) => {
countRendering?.();
return <div {...props}>{children}</div>
})
// eslint-disable-next-line @typescript-eslint/no-unused-vars
let outerCount = 1
// ์ปดํฌ๋ํธ ๋ฐ์ ์ ์ํ ๊ฐ์ฒด๋ ํจ์๊ฐ์ ์ฐธ์กฐํ์
์ ํ๋ก๊ทธ๋จ์ด ์คํ๋ ๋ ํ๋ฒ ์์ฑ๋์ด์
// ์ปดํฌ๋ํธ ์์์ ๋ฐ์ ์ ์๋ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด๋ ์ฃผ์๊ฐ์ ๊ฐ์๊ณณ์ ๋ฐ๋ผ๋ณด๊ณ ์๊ธฐ๋๋ฌธ์ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ ์ ์๋ค.
const style = { width: '100px', height: '100px' }
const onClick = () => {
outerCount += 1;
}
export default function RequireRefactoring({ countRendering }: Props) {
return (
<PureComponent
// ์ฒซ๋ฒ์งธ ๋ฌธ์ ์ . ๊ฐ์ฒด๋ก props๋ฅผ ์ ๋ฌํ๋ฉด ์ปดํฌ๋ํธ์์ ๊ฐ์ฒด๋ ํญ์ ๊ฐ์ ๊ฐ์๋ ์๋ก ์์ฑ๋๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ์ฃผ์๊ฐ์ ๊ฐ์ ธ์ ์๋ก์ด ๊ฐ์ฒด๋ก ๊ฐ์ฃผํด์ ๋ฆฌ๋ ๋๋ง๋จ.
style={style}
// ๋๋ฒ์งธ ๋ฌธ์ ์ . onClick์ ์ ๋ฌ๋ ํจ์๋ ์ฐธ์กฐํ์
์ด๊ธฐ ๋๋ฌธ์ ๋ด์ฉ์ด ๊ฐ๋๋ผ๋ ์๋ก์ด ํจ์๋ก ๊ฐ์ฃผํด์ ๋ฆฌ๋ ๋๋ง๋จ.
onClick={onClick}
countRendering={countRendering}
>
test component
</PureComponent>
);
}
/** ๋ด๊ฐ ์๋ชป ์๊ฐํ๊ฒ : ์ ์ปดํฌ๋ํธ ์์ ๊ฐ์ฒด๋ ๋ค๋ฅธ ์ฃผ์๊ฐ์ ๊ฐ์ง์ง?? react์์ ์ผ๋ถ๋ฌ ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๊ฒ ํด์ ํด๋น ์ปดํฌ๋ํธ์ ๋ฆฌ๋ ๋๋ง์ ์ผ์ผํค๊ธฐ ์ํ๊ฑด๊ฐ??
* ์ปดํฌ๋ํธ๋ ๊ฒฐ๊ตญ ํ๋์ ํจ์๋ผ๋๊ฒ์ ๊น๋นกํจ..ใ
* ์ปดํฌ๋ํธ๋ ํจ์์ด๊ธฐ ๋๋ฌธ์ ํธ์ถ๋ ๋๋ง๋ค ์๋ก์ด ์คํ์ปจํ
์คํธ๋ฅผ ์์ฑํ๋ค.
* ๊ทธ๋์ ๋ด๋ถ์ ๋ณ์๋ ๊ฐ์ฒด๋ ์๋ก์ด ์คํ์ปจํ
์คํธ ๋ด์์ ์๋ก ์์ฑ๋๋ค.
* ๊ทธ๋์ ๋์ผํ ์ฝ๋๋ผ๋ ๋ฆฌ๋ ๋๋งํ๋ฉด ์ปดํฌ๋ํธ์์ ์ฐธ์กฐํ์
๋ค(๊ฐ์ฒด, ๋ฐฐ์ด, ํจ์ ๋ฑ)์ ์๋ก์ด ์ฃผ์๋ฅผ ์ฐธ์กฐํ๋ค.
*/
๐ฃ useMyRef
import { useMemo } from "react"
export function useMyRef<T>(initValue: T | null) {
const ref = useMemo(()=>{
return { current: initValue };
},[])
return ref;
}
// ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ฐธ์กฐํ์
์ ๋ฐํํ์ง ์๋๋ค.
// ๊ทธ๋ผ ์ง๊ธ ๋ฌธ์ ๋ ๋ฆฌ๋ ๋๋ง ๋ฒํผ์ ๋๋ฅผ๋๋ง๋ค ๊ณ์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค๋ ๊ฑด๋ฐ,
// useMyRef๋ ํจ์. ํจ์๋ ์คํ๋ ๋๋ง๋ค ์๋ก์ด ์คํ์ปจํ
์คํธ๊ฐ ์์ฑ๋๊ธฐ ๋๋ฌธ์
// ๊ทธ ์์ ๊ฐ์ฒด๋ ๊ฐ์ ๊ฐ์ด์ฌ๋ ์๋ก์ด ์ฃผ์์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
// ๋ฆฌ๋ ๋๋ง ๋ ๋ ๋ฉ๋ชจ์ด์ ์ด์
ํ
๋ค๋ก ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ๋ชปํ๊ฒ ๋ง์์ผ ํ๋..?
// useMemo๋ฅผ ์ฌ์ฉํ๋ฉด ๊ณ์ฐ๋๊ฐ์ ์บ์ฑ์ ํ๊ธฐ๋๋ฌธ์ ์์กด์ฑ ๋ฐฐ์ด์ ๊ฐ์ด ๋ฐ๋๋๊น์ง ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฐธ์กฐ๋ฅผ ํ๋ค.
// useRef๋ .current ๊ฐ์ ๋ฐ๊ฟ๋ ํญ์ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
// ์ด ์ปค์คํ
ํ
์๋ ๋์ผํ๊ฒ ํด์ฃผ๊ธฐ ์ํด์ ์์กด์ฑ ๋ฐฐ์ด์ ๋น์ด๋ค.
// ์์กด์ฑ ๋ฐฐ์ด์ ๋น์ฐ๋ฉด ๋ค์ ๊ณ์ฐํด์ผ๋ ๊ธฐ์ค์ด ์๊ธฐ๋๋ฌธ์
// ์ฒ์ ๋ ๋๋ง ๋์์๋ ๊ณ์ฐ๋ ๊ฐ์ ์ด๋ค ๋ฉ๋ชจ๋ฆฌ์ ๊ฐ์ ์ ์ฅํ๊ณ ๊ทธ ๋ค์๋ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐธ์กฐํ๋ค.
// ๊ทธ๋ฌ๋ฉด ๊ฐ์ฒด๋ด๋ถ์ ๊ฐ์ ๋ฐ๋์ด๋ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐธ์กฐํด์ useRef์ ๋น์ทํ์ง ์์๊น...?
์ด๊ฑด ๋์ ํ์ด
import { useState } from "react";
export function useMyRef<T>(initValue: T | null) {
// ์ฌ์ค ref๋ state์ ํ ์ข
๋ฅ์
๋๋ค. set์ ํ์ง ์๊ธฐ ๋๋ฌธ์, ์ธ์ ๋ ๋์ผํ state๋ก ์กด์ฌํฉ๋๋ค.
const [ref] = useState<{ current: typeof initValue}>({ current: initValue });
return ref
}
์ด๊ฑด ์ ๋ต..
๋๋ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐธ์กฐํ๋๊ฒ์๋ง ์ง์คํ๋๋ฐ ์ ๋ต์ ๋ณด๊ณ ์ํ! ํ๋คใ
ํ๋ฉด์ ๋ฐ๋ ๋ด์ฉ์ ๋ณด์ฌ์ฃผ๋ ค๋ฉด useState๋ ๋ฌด์กฐ๊ฑด ๋ถ๋ณ์ฑ์ ์ง์ผ์ผํ๋ค!๋ฅผ ๋ค์ง๋ ์๊ฐ์ด์๋ค.
setter ํจ์๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์ํ ๊ฐ์ฒด ์์ฑ์ ์ง์ ๋ณ๊ฒฝํด์ ๋ถ๋ณ์ฑ์ ์งํค์ง ์์๊ธฐ ๋๋ฌธ์ ๋์ผํ ์ฐธ์กฐ๋ฅผ ์ ์งํ ์ ์๋ค.
tmi...
3์ฃผ๋์ ํ๊ฑธ ์ ๋ฆฌํ๋ฉด์ ๋ฉํ ๋์ ํผ๋๋ฐฑ์ ๋ณด๋๋ฐ ๋์๊ฒ ์์ง ํ๋ํ ๋์ด๋(ใ ใ )๋ก ์ธํด
์ฒซ ์ฃผ๋ง ๋์ ์๊ฐ์ ํ ๋๋ก ์ ๋ฆฌํด์ ๊ณผ์ ๋ฅผ ๋ผ ์ ์์๊ณ , ๊ทธ์ ๋ํ ํผ๋๋ฐฑ์ ๋ฐ์ ์ ์์๋ค..
ํ....ใ
ใ
ใ
2,3์ฃผ์ฐจ ๋๋ฌด ์ด๋ ค์์๐
'Javascript ๊ณต๋ถ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
2. JS์ ๋ค์ํ ๊ฐ ๋น๊ต์ ์์ ๋น๊ต, ๊น์ ๋น๊ต (0) | 2024.07.08 |
---|---|
19. ํจ์์ ์ผ๊ธ ๊ฐ์ฒด (0) | 2023.08.05 |
18. let, const ํค์๋์ ๋ธ๋ก ๋ ๋ฒจ ์ค์ฝํ (0) | 2023.07.29 |
17. ์ ์ญ ๋ณ์์ ๋ฌธ์ ์ (0) | 2023.07.29 |
16. ์ค์ฝํ (0) | 2023.07.22 |