cache
cache
๋ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ ์ฐ์ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์บ์ฑํ๊ฒ ํด์ค๋๋ค.
const cachedFn = cache(fn);
์ฐธ์กฐ
cache(fn)
์ปดํฌ๋ํธ ์ธ๋ถ์์ cache
๋ฅผ ํธ์ถํด ์บ์ฑ ๊ธฐ๋ฅ์ ๊ฐ์ง ํจ์์ ํ ๋ฒ์ ์ ๋ง๋ค ์ ์์ต๋๋ค.
import {cache} from 'react';
import calculateMetrics from 'lib/metrics';
const getMetrics = cache(calculateMetrics);
function Chart({data}) {
const report = getMetrics(data);
// ...
}
getMetrics
๊ฐ ์ฒ์ data
๋ฅผ ํธ์ถํ ๋, getMetrics
๋ calculateMetrics(data)
๋ฅผ ํธ์ถํ๊ณ ์บ์์ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํฉ๋๋ค. getMetrics
๊ฐ ๊ฐ์ data
์ ํจ๊ป ๋ค์ ํธ์ถ๋๋ฉด, calculateMetrics(data)
๋ฅผ ๋ค์ ํธ์ถํ๋ ๋์ ์ ์บ์ฑ ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
์๋์ ์๋ ์์๋ฅผ ์ฐธ๊ณ ํ์ธ์.
๋งค๊ฐ๋ณ์
fn
: ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๊ณ ์ถ์ ํจ์.fn
๋ ์ด๋ค ์ธ์๊ฐ๋ ๋ฐ์ ์ ์๊ณ ์ด๋ค ๊ฒฐ๊ณผ๋ ๋ฐํํ ์ ์์ต๋๋ค.
๋ฐํ๊ฐ
cache
๋ ๊ฐ์ ํ์
์๊ทธ๋์ฒ๋ฅผ ๊ฐ์ง fn
์ ์บ์ฑ ๋ ๋ฒ์ ์ ๋ฐํํฉ๋๋ค. ์ด ๊ณผ์ ์์ fn
๋ฅผ ํธ์ถํ์ง ์์ต๋๋ค.
์ฃผ์ด์ง ์ธ์๊ฐ๊ณผ ํจ๊ป cachedFn
๋ฅผ ํธ์ถํ ๋, ์บ์์ ์บ์ฑ ๋ ๋ฐ์ดํฐ๊ฐ ์๋์ง ๋จผ์ ํ์ธํฉ๋๋ค. ๋ง์ฝ ์บ์ฑ ๋ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด, ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค. ๋ง์ฝ ์๋ค๋ฉด, ๋งค๊ฐ๋ณ์์ ํจ๊ป fn
์ ํธ์ถํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์บ์์ ์ ์ฅํ๊ณ ๊ฐ์ ๋ฐํํฉ๋๋ค. fn
๊ฐ ์ ์ผํ๊ฒ ํธ์ถ๋๋ ๊ฒฝ์ฐ๋ ์บ์ฑ ๋ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ์
๋๋ค.
์ฃผ์
- React๋ ์๋ฒ ์์ฒญ๋ง๋ค ๋ชจ๋ ๋ฉ๋ชจํ๋ ํจ์๋ค์ ์ํด ์บ์๋ฅผ ๋ฌดํจํํฉ๋๋ค.
cache
๋ฅผ ํธ์ถํ ๋๋ง๋ค ์ ํจ์๊ฐ ์์ฑ๋ฉ๋๋ค. ์ฆ, ๋์ผํ ํจ์๋กcache
๋ฅผ ์ฌ๋ฌ ๋ฒ ํธ์ถํ๋ฉด ๋์ผํ ์บ์๋ฅผ ๊ณต์ ํ์ง ์๋ ๋ค๋ฅธ ๋ฉ๋ชจํ๋ ํจ์๊ฐ ๋ฐํ๋ฉ๋๋ค.cachedFn
๋ํ ์บ์ ์๋ฌ๋ฅผ ์ก์๋ ๋๋ค.fn
๊ฐ ํน์ ์ธ์์ ๋ํด ์๋ฌ๋ฅผ ๋์ง๋ฉด ์บ์ฑ ๋๊ณ , ๋์ผํ ์ธ์๋กcachedFn
๋ฅผ ํธ์ถํ๋ฉด ๋์ผํ ์๋ฌ๊ฐ ๋ค์ ๋ฐ์ํฉ๋๋ค.cache
๋ ์๋ฒ ์ปดํฌ๋ํธ์์๋ง ์ฌ์ฉ๊ฐ๋ฅํฉ๋๋ค.
์ฌ์ฉ๋ฒ
๊ณ ๋น์ฉ ์ฐ์ฐ ์บ์ฑํ๊ธฐ
๋ฐ๋ณต ์์
์ ํผํ๊ธฐ ์ํด cache
๋ฅผ ์ฌ์ฉํ์ธ์.
import {cache} from 'react';
import calculateUserMetrics from 'lib/user';
const getUserMetrics = cache(calculateUserMetrics);
function Profile({user}) {
const metrics = getUserMetrics(user);
// ...
}
function TeamReport({users}) {
for (let user in users) {
const metrics = getUserMetrics(user);
// ...
}
// ...
}
๊ฐ์ user
๊ฐ์ฒด๊ฐ Profile
๊ณผ TeamReport
์์ ๋ ๋๋ ๋, ๋ ์ปดํฌ๋ํธ๋ ์ผ์ ๊ณต์ ํ๊ณ , user
๋ฅผ ์ํ calculateUserMetrics
๋ฅผ ํ ๋ฒ๋ง ํธ์ถํฉ๋๋ค.
Profile
์ด ๋จผ์ ๋ ๋๋๋ค๊ณ ๊ฐ์ ํด ๋ด
์๋ค. Profile
์ getUserMetrics
๋ฅผ ํธ์ถํ๊ณ , ์บ์ฑ ๋ ๊ฒฐ๊ณผ๊ฐ ์๋์ง ํ์ธํฉ๋๋ค. user
์ ํจ๊ป getUserMetrics
๋ฅผ ์ฒ์ ํธ์ถํ๊ธฐ ๋๋ฌธ์, ํ์ฌ ์ ์ฅ๋ ์บ์๋ ์์ต๋๋ค. getUserMetrics
๋ user
์ ํจ๊ป calculateUserMetrics
๋ฅผ ํธ์ถํ๊ณ ์บ์์ ๊ฒฐ๊ด๊ฐ์ ์ ์ฅํฉ๋๋ค.
TeamReport
๊ฐ users
๋ชฉ๋ก๊ณผ ํจ๊ป ๋ ๋๋ ๋ ๊ฐ์ user
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๊ฒ ๋๊ณ , ์ด๋ getUserMetrics
๋ฅผ ํธ์ถํด ์บ์์์ ๊ฒฐ๊ด๊ฐ์ ์ฝ์ด์ต๋๋ค.
๋ฐ์ดํฐ์ ์ค๋ ์ท ๊ณต์ ํ๊ธฐ
์ปดํฌ๋ํธ๋ผ๋ฆฌ ๋ฐ์ดํฐ์ ์ค๋
์ท์ ๊ณต์ ํ๊ธฐ ์ํด์ fetch
์ ๊ฐ์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ํจ์์ ํจ๊ป cache
๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ ๋, ์์ฒญ์ด ํ ๋ฒ๋ง ๋ฐ์ํ๊ณ ๋ฐ์์จ ๋ฐ์ดํฐ๋ ์บ์ฑ ๋๋ฉฐ ์ปดํฌ๋ํธ๋ผ๋ฆฌ ๊ณต์ ๋ฉ๋๋ค. ๋ชจ๋ ์ปดํฌ๋ํธ๋ ์๋ฒ ๋ ๋๋ง ์ ๋ฐ์ ๊ฑธ์ณ ๋์ผํ ๋ฐ์ดํฐ ์ค๋
์ท์ ์ฐธ์กฐํฉ๋๋ค.
import {cache} from 'react';
import {fetchTemperature} from './api.js';
const getTemperature = cache(async (city) => {
return await fetchTemperature(city);
});
async function AnimatedWeatherCard({city}) {
const temperature = await getTemperature(city);
// ...
}
async function MinimalWeatherCard({city}) {
const temperature = await getTemperature(city);
// ...
}
AnimatedWeatherCard
์ MinimalWeatherCard
๊ฐ ๊ฐ์ ๋์๋ฅผ ๋ ๋๋งํ ๋, ๋ฉ๋ชจํ๋ ํจ์๋ก ๋ถํฐ ๊ฐ์ ๋ฐ์ดํฐ์ ์ค๋
์ท์ ๋ฐ๊ฒ ๋ฉ๋๋ค.
AnimatedWeatherCard
์ MinimalWeatherCard
๊ฐ ๋ค๋ฅธ ๋์๋ฅผ getTemperature
์ ์ธ์๋ก ๋ฐ๊ฒ ๋๋ค๋ฉด, fetchTemperature
๋ ๋ ๋ฒ ํธ์ถ๋๊ณ ํธ์ถ๋ง๋ค ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ฒ ๋ฉ๋๋ค.
๋์๊ฐ ์บ์ ํค์ฒ๋ผ ๋์ํ๊ฒ ๋ฉ๋๋ค.
์ฌ์ ์ ๋ฐ์ดํฐ ๋ฐ์๋๊ธฐ
์ฅ์๊ฐ ์คํ๋๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์บ์ฑํ๋ฉด, ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๊ธฐ ์ ์ ๋น๋๊ธฐ ์์ ์ ์์ํ ์ ์์ต๋๋ค.
const getUser = cache(async (id) => {
return await db.user.query(id);
}
async function Profile({id}) {
const user = await getUser(id);
return (
<section>
<img src={user.profilePic} />
<h2>{user.name}</h2>
</section>
);
}
function Page({id}) {
// โ
Good: ์ ์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์์ํฉ๋๋ค.
getUser(id);
// ... ๋ช๋ช์ ๊ณ์ฐ ์์
๋ค
return (
<>
<Profile id={id} />
</>
);
}
Page
๋ฅผ ๋ ๋๋งํ ๋, ์ปดํฌ๋ํธ๋ getUser
๋ฅผ ํธ์ถํ์ง๋ง, ๋ฐํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค๋ ์ ์ ์ ์ํ์ธ์. ์ด ์ด๊ธฐ getUser
ํธ์ถ์ ํ์ด์ง๊ฐ ๋ค๋ฅธ ๊ณ์ฐ ์์
์ ์ํํ๊ณ ์์์ ๋ ๋๋งํ๋ ๋์ ๋ฐ์ํ๋, ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ๋ฅผ ์์ํฉ๋๋ค.
Profile
์ ๋ ๋๋งํ ๋, getUser
๋ฅผ ๋ค์ ํธ์ถํฉ๋๋ค. ์ด๊ธฐ getUser
ํธ์ถ์ด ์ด๋ฏธ ์ ์ ๋ฐ์ดํฐ์ ๋ฐํ๋๊ณ ์บ์ฑ ๋์๋ค๋ฉด, Profile
์ด ํด๋น ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ ๊ธฐ๋ค๋ฆด ๋, ๋ค๋ฅธ ์๊ฒฉ ํ๋ก์์ ํธ์ถ ์์ด ์ฝ๊ฒ ์บ์์์ ์ฝ์ด์ฌ ์ ์์ต๋๋ค. ์ด๊ธฐ ๋ฐ์ดํฐ ์์ฒญ์ด ์๋ฃ๋์ง ์์ ๊ฒฝ์ฐ, ์ด ํจํด์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ก๋ํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ ๋ ์๊ธฐ๋ ์ง์ฐ์ด ์ค์ด๋ญ๋๋ค.
Deep Dive
๋น๋๊ธฐ ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด, Promise๋ฅผ ๋ฐ์ต๋๋ค. ์ด Promise๋ ์์ ์ ๋ํ ์ํ(๋ณด๋ฅ ์ค, ์๋ฃ๋จ, ์คํจํจ)์ ์ต์ข ์ ์ผ๋ก ํ์ ๋ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
์ด ์์์์, ๋น๋๊ธฐ ํจ์ fetchData
๋ fetch
๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ Promise๋ฅผ ๋ฐํํฉ๋๋ค.
async function fetchData() {
return await fetch(`https://...`);
}
const getData = cache(fetchData);
async function MyComponent() {
getData();
// ... some computational work
await getData();
// ...
}
getData
๋ฅผ ์ฒ์ ํธ์ถํ ๋, fetchData
์์ ๋ฐํ๋ Promise๊ฐ ์บ์ฑ ๋ฉ๋๋ค. ์ดํ ์กฐํ ์, ๊ฐ์ Promise๋ฅผ ๋ฐํํฉ๋๋ค.
์ฒซ ๋ฒ์งธ getData
ํธ์ถ์ ๊ธฐ๋ค๋ฆฌ์ง ์์ง๋ง(await)
๋ ๋ฒ์งธ๋ ๊ธฐ๋ค๋ฆฝ๋๋ค. await
๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฐ์ฐ์๋ก, ๊ธฐ๋ค๋ ธ๋ค๊ฐ ํ์ ๋ Promise์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค. ์ฒซ ๋ฒ์งธ getData
์ ๋จ์ํ ์กฐํํ ๋ ๋ฒ์งธ getData
์ ๋ํ Promise๋ฅผ ์บ์ฑํ๊ธฐ ์ํด fetch
๋ฅผ ์คํํฉ๋๋ค.
๋ ๋ฒ์งธ ํธ์ถ์์ Promise๊ฐ ์ฌ์ ํ _๋ณด๋ฅ ์ค_์ด๋ฉด, ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ await
๊ฐ ์ผ์ ์ค์ง๋ฉ๋๋ค. ์ด ์ต์ ํ๋ ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ React๊ฐ ๊ณ์ฐ ์์
์ ๊ณ์ํ ์ ์๊ฒ ํด ๋ ๋ฒ์งธ ํธ์ถ์ ๋ํ ๋๊ธฐ ์๊ฐ์ ์ค์ผ ์ ์๊ฒ ํฉ๋๋ค.
์๋ฃ๋ ๊ฒฐ๊ณผ๋ ์๋ฌ์ ๋ํ Promise๊ฐ ์ด๋ฏธ ์ ํด์ง ๊ฒฝ์ฐ, await
๋ ์ฆ์ ๊ฐ์ ๋ฐํํฉ๋๋ค. ๋ ๊ฒฐ๊ณผ ๋ชจ๋ ์ฑ๋ฅ์์ ์ด์ ์ด ์์ต๋๋ค.
Deep Dive
์ธ๊ธ๋ ๋ชจ๋ API๋ค์ ๋ฉ๋ชจ์ด์ ์ด์ ์ ์ ๊ณตํ์ง๋ง, ๋ฉ๋ชจํ ๋์, ์บ์ ์ ๊ทผ ๊ถํ, ์บ์ ๋ฌดํจํ ์์ ์ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
useMemo
์ผ๋ฐ์ ์ผ๋ก useMemo
๋ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์์ ๋ ๋๋ง์ ๊ฑธ์ณ ๊ณ ๋น์ฉ์ ๊ณ์ฐ์ ์บ์ฑํ ๋ ์ฌ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ปดํฌ๋ํธ ๋ด์์ ๋ฐ์ดํฐ์ ๋ณํ์ ๋ฉ๋ชจํํ ์ ์์ต๋๋ค.
'use client';
function WeatherReport({record}) {
const avgTemp = useMemo(() => calculateAvg(record)), record);
// ...
}
function App() {
const record = getRecord();
return (
<>
<WeatherReport record={record} />
<WeatherReport record={record} />
</>
);
}
์ด ์์์์ App
์ ๋ ๊ฐ์ WeatherReport
๋ฅผ ๊ฐ์ ๋ฐ์ดํฐ์ ํจ๊ป ๋ ๋ํ์ต๋๋ค. ๋ ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ ์์
์ ์ํํ์์๋ ๋ถ๊ตฌํ๊ณ ์๋ก ์์
์ ๊ณต์ ํ์ง ์์ต๋๋ค. useMemo
์ ์บ์๋ ํด๋น ์ปดํฌ๋ํธ ๋ด๋ถ์๋ง ์์ต๋๋ค.
ํ์ง๋ง useMemo
๋ App
์ด ๋ค์ ๋ ๋๋ง ๋๊ณ record
๊ฐ์ฒด๊ฐ ๋ณ๊ฒฝ๋์ง ์๋ ๊ฒฝ์ฐ, ๊ฐ ์ปดํฌ๋ํธ ์ธ์คํด์ค๊ฐ ์์
์ ๊ฑด๋๋ฐ๊ณ ๋ฉ๋ชจํ๋ avgTemp
์ ๊ฐ์ ์ฌ์ฉํฉ๋๋ค. useMemo
๋ ์ฃผ์ด์ง ์ข
์์ฑ์ ๊ฐ์ง avgTemp
์ ๋ง์ง๋ง ๊ณ์ฐ๋ง ์บ์ฑํฉ๋๋ค.
cache
์ผ๋ฐ์ ์ผ๋ก cache
๋ ์๋ฒ ์ปดํฌ๋ํธ์์ ์ปดํฌ๋ํธ ๊ฐ์ ๊ณต์ ํ ์ ์๋ ์์
์ ๋ฉ๋ชจํํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
const cachedFetchReport = cache(fetchReport);
function WeatherReport({city}) {
const report = cachedFetchReport(city);
// ...
}
function App() {
const city = "Los Angeles";
return (
<>
<WeatherReport city={city} />
<WeatherReport city={city} />
</>
);
}
์ด์ ์์ ๋ฅผ cache
๋ฅผ ์ด์ฉํด ์ฌ์์ฑํ๋ฉด, ์ด ๊ฒฝ์ฐ์ WeatherReport
์ ๋ ๋ฒ์งธ ์ธ์คํด์ค๋ ์ค๋ณต ์์
์ ์๋ตํ๊ณ ์ฒซ ๋ฒ์งธ WeatherReport
์ ๊ฐ์ ์บ์๋ฅผ ์ฝ๊ฒ ๋ฉ๋๋ค. ์ด์ ์์ ์ ๋ค๋ฅธ ์ ์ ๊ณ์ฐ์๋ง ์ฌ์ฉ๋๋ useMemo
์ ๋ฌ๋ฆฌ cache
๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ฉ๋ชจํํ๋ ๋ฐ๋ ๊ถ์ฅ๋๋ค๋ ์ ์
๋๋ค.
์ด๋, cache
๋ ์๋ฒ ์ปดํฌ๋ํธ์์๋ง ์ฌ์ฉํด์ผ ํ๋ฉฐ ์บ์๋ ์๋ฒ ์์ฒญ ์ ์ฒด์์ ๋ฌดํจํ๊ฐ ๋ฉ๋๋ค.
memo
memo
๋ ํ๋กํผํฐ๊ฐ ๋ณ๊ฒฝ๋์ง ์์์ ๋ ์ปดํฌ๋ํธ๊ฐ ์ฌ ๋ ๋๋ง ๋๋ ๊ฒ์ ๋ง๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
'use client';
function WeatherReport({record}) {
const avgTemp = calculateAvg(record);
// ...
}
const MemoWeatherReport = memo(WeatherReport);
function App() {
const record = getRecord();
return (
<>
<MemoWeatherReport record={record} />
<MemoWeatherReport record={record} />
</>
);
}
์์ ์์ MemoWeatherReport
์ปดํฌ๋ํธ ๋ชจ๋ ์ฒซ ๋ฒ์งธ ๋ ๋์์ calculateAvg
๋ฅผ ํธ์ถํฉ๋๋ค. ํ์ง๋ง App
์ด ์ฌ ๋ ๋๋ง ๋ ๋ record
์ ๋ณ๊ฒฝ์ด ์๋ค๋ฉด ํ๋กํผํฐ์ ๋ณ๊ฒฝ์ด ์๊ธฐ ๋๋ฌธ์ MemoWeatherReport
๊ฐ ๋ค์ ๋ ๋๋ง ๋์ง ์์ต๋๋ค.
useMemo
์ ๋น๊ตํ๋ฉด memo
๋ ํ๋กํผํฐ์ ํน์ ๊ณ์ฐ์ ๊ธฐ๋ฐ์ผ๋ก ์ปดํฌ๋ํธ ๋ ๋๋ง์ ๋ฉ๋ชจํํฉ๋๋ค. useMemo
์ ์ ์ฌํ๊ฒ, ๋ฉ๋ชจํ๋ ์ปดํฌ๋ํธ๋ ๋ง์ง๋ง ํ๋กํผํฐ ๊ฐ์ ๋ํ ๋ง์ง๋ง ๋ ๋๋ง์ ์บ์ฑํฉ๋๋ค. ํ๋กํผํฐ๊ฐ ๋ณ๊ฒฝ๋๋ฉด, ์บ์ฌ๋ ๋ฌดํจํ๋๊ณ ์ปดํฌ๋ํธ๋ ์ฌ ๋ ๋๋ง ๋ฉ๋๋ค.
๋ฌธ์ ํด๊ฒฐ
๋์ผํ ์ธ์๋ก ํจ์๋ฅผ ํธ์ถํด๋ ๋ฉ๋ชจ๋ ํจ์๊ฐ ๊ณ์ ์คํ๋ฉ๋๋ค.
์์ ์ธ๊ธ๋ ์ฃผ์ ์ฌํญ๋ค์ ํ์ธํ์ธ์.
- ๋ค๋ฅธ ๋ฉ๋ชจํ๋ ํจ์๋ฅผ ํธ์ถํ๋ฉด ๋ค๋ฅธ ์บ์์์ ์ฝ์ต๋๋ค.
- ์ปดํฌ๋ํธ ์ธ๋ถ์์ ๋ฉ๋ชจํ๋ ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ์บ์๊ฐ ์ฌ์ฉ๋์ง ์์ต๋๋ค.
์์ ์ด๋ ๊ฒ๋ ํด๋นํ์ง ์๋๋ค๋ฉด, React๊ฐ ์บ์์ ๋ฌด์์ด ์กด์ฌํ๋์ง ํ์ธํ๋ ๋ฐฉ์์ ๋ฌธ์ ๊ฐ ์์ ์ ์์ต๋๋ค.
์ธ์๊ฐ ์์ ๊ฐ(๊ฐ์ฒด, ํจ์, ๋ฐฐ์ด ๋ฑ) ์ด ์๋๋ผ๋ฉด, ๊ฐ์ ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ๋๊ฒผ๋์ง ํ์ธํ์ธ์.
๋ฉ๋ชจํ๋ ํจ์ ํธ์ถ ์, React๋ ์ ๋ ฅ๋ ์ธ์๊ฐ์ ์กฐํํด ๊ฒฐ๊ณผ๊ฐ ์ด๋ฏธ ์บ์ฑ ๋์ด ์๋์ง ํ์ธํฉ๋๋ค. React๋ ์ธ์์ ์์ ๋๋ฑ์ฑ์ ์ฌ์ฉํด ์บ์ ํํธ๊ฐ ์๋์ง๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
import {cache} from 'react';
const calculateNorm = cache((vector) => {
// ...
});
function MapMarker(props) {
// ๐ฉ Wrong: ์ธ์๊ฐ ๋งค ๋ ๋๋ง๋ง๋ค ๋ณ๊ฒฝ๋๋ ๊ฐ์ฒด์
๋๋ค.
const length = calculateNorm(props);
// ...
}
function App() {
return (
<>
<MapMarker x={10} y={10} z={10} />
<MapMarker x={10} y={10} z={10} />
</>
);
}
์ด ๊ฒฝ์ฐ ๋ MapMarker
๋ ๋์ผํ ์์
์ ์ํํ๊ณ ๋์ผํ ๊ฐ์ธ {x: 10, y: 10, z:10}
์ ํจ๊ป calculateNorm
๋ฅผ ํธ์ถํ๋ ๋ฏ ๋ณด์
๋๋ค. ๊ฐ์ฒด์ ๋์ผํ ๊ฐ์ด ํฌํจ๋์ด ์๋๋ผ๋ ๊ฐ ์ปดํฌ๋ํธ๊ฐ ์์ฒด ํ๋กํผํฐ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฏ๋ก, ๋์ผํ ๊ฐ์ฒด ์ฐธ์กฐ๊ฐ ์๋๋๋ค.
React๋ ์
๋ ฅ์์ Object.is
๋ฅผ ํธ์ถํด ์บ์ ํํธ๊ฐ ์๋์ง ํ์ธํฉ๋๋ค.
import {cache} from 'react';
const calculateNorm = cache((x, y, z) => {
// ...
});
function MapMarker(props) {
// โ
Good: ๋ฉ๋ชจํ ํจ์์ ์ธ์๋ก ์์๊ฐ ์ ๊ณตํ๊ธฐ
const length = calculateNorm(props.x, props.y, props.z);
// ...
}
function App() {
return (
<>
<MapMarker x={10} y={10} z={10} />
<MapMarker x={10} y={10} z={10} />
</>
);
}
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ํ ๊ฐ์ง ๋ฐฉ๋ฒ์ ๋ฒกํฐ ์ฐจ์์ calculateNorm
์ ์ ๋ฌํ๋ ๊ฒ์
๋๋ค. ์ฐจ์ ์์ฒด๊ฐ ์์ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํฉ๋๋ค.
๋ค๋ฅธ ๋ฐฉ๋ฒ์ ๋ฒกํฐ ๊ฐ์ฒด๋ฅผ ์ปดํฌ๋ํธ์ ํ๋กํผํฐ๋ก ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ๋ ์ปดํฌ๋ํธ ์ธ์คํด์ค์ ๋์ผํ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํด์ผ ํฉ๋๋ค.
import {cache} from 'react';
const calculateNorm = cache((vector) => {
// ...
});
function MapMarker(props) {
// โ
Good: ๋์ผํ `vector` ๊ฐ์ฒด๋ฅผ ๋๊ฒจ์ค๋๋ค.
const length = calculateNorm(props.vector);
// ...
}
function App() {
const vector = [10, 10, 10];
return (
<>
<MapMarker vector={vector} />
<MapMarker vector={vector} />
</>
);
}