๐ ์ฝ๋ ์ค์ฟผ๋ ์์ ๋์ค ๋๋ฌด ์ ๊ธฐํ๊ณ ์ค์ํ ๋ด์ฉ์ ๋ฃ๊ฒ ๋์ด ์์ ๋์ค ๊ณต์ ํด ์ฃผ์ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ธ ๊ณต๋ถ๋ฅผ ์ํด ๊ฐ๋จํ๊ฒ ์ ๋ฆฌํด๋ณด์์ต๋๋ค ~
๊ฐ๋จํ ์ฝ๋๋ก ๋ฆฌ๋ ๋๋ง ์ต์ ํ์ ๋ํด ๊ณต๋ถ๋ฅผ ํด๋ด ์๋ค.
import React, { useCallback, useState } from "react";
import "./styles.css";
export default function App() {
console.log("App");
const [, setState] = useState();
return (
<div className="App">
<h1>react performance</h1>
<button onClick={() => setState(Math.random())}>๋ถ๋ชจ๊ฐ์ ๋ ๋๋ง</button>
<Child data="str" />
</div>
);
}
function Child(props) {
console.log("Child");
return <div>{props.data}</div>;
}
๋ ๋๋ง ๋ ๋๋ง๋ค App์์ console.log("App")
์ ์ฐ๊ณ , ๋ถ๋ฌ์จ ์์์ปดํฌ๋ํธ๋ console.log("Child")
๋ฅผ ์คํ์์ผ์ค์ ๋ฆฌ๋ ๋๋ง์ด ๋๋์ง ํ์ธํด๋ด
์๋ค.
์ฝ๋๋ฅผ ์คํ์ํค๋ฉด ์ด๋ฐ ์ฐฝ์ด ๋น๋๋ค.
์ผ๋จ ํด๋น ์ฝ๋๋ฅผ ์คํ์ํค๊ณ ๋ฒํผ์ 2~3๋ฒ ๋๋ฅด๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋ํ๋ฉ๋๋ค.
Child์ ๋ณํ๊ฐ ์์ง๋ง ๊ณ์ ๋ ๋๋ง ๋๋ ๊ฒ์ ๋ณด์ค ์ ์์ต๋๋ค.
React.memo๋ก child๋ฅผ ๊ฐ์ธ๋ณด๊ฒ ์ต๋๋ค.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
console.log("App");
const [, setState] = useState();
return (
<div className="App">
<h1>react performance</h1>
<button onClick={() => setState(Math.random())}>๋ถ๋ชจ๊ฐ์ ๋ ๋๋ง</button>
<MemoChild data="str" />
</div>
);
}
function Child(props) {
console.log("Child");
return <div>{props.data}</div>;
}
export const MemoChild = React.memo(Child);
๊ทธ๋ฌ๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋ํ๋ฉ๋๋ค.
๋ณด์๋๊ฒ๊ณผ ๊ฐ์ด child๊ฐ ๋ฆฌ๋ ๋๋ง๋์ง ์์ต๋๋ค.
์์ ์ ๋ค์ผ๋ฉด์ ์ข ์ ๊ธฐํ? ์ต์ ํ ํ ์คํ ๋ฐฉ๋ฒ์ด ์๊ธฐ์ ๊ธฐ๋ก๊ฒธ ๊ณต์ ํด๋ด ๋๋ค.
ํ์ฌ react.memo๋ฅผ ์ด ์ํ์ด๊ธฐ์, Child ์ปดํฌ๋ํธ๊ฐ ๋ค์ ๋ ๋๋ง ๋์ง ์์๋ค๊ณ ๋น๋๋ค.
clickHandler์ด๋ผ๋ ํจ์๋ฅผ ๋ง๋ค์ด์ MemoChild์ ๋ด๋ ค์ฃผ๊ฒ ์ต๋๋ค.
import React, { useCallback, useState } from "react";
import "./styles.css";
export default function App() {
console.log("App");
const [, setState] = useState();
const clickHandler = () => console.log("Clicked");
return (
<div className="App">
<h1>react performance</h1>
<button onClick={() => setState(Math.random())}>๋ถ๋ชจ๊ฐ์ ๋ ๋๋ง</button>
<MemoChild clickHandler={clickHandler} data="str" />
</div>
);
}
function Child(props) {
console.log("Child");
return <div>{props.data}</div>;
}
export const MemoChild = React.memo(Child);
๋ญ๊ฐ React.memo๊ฐ ์์์ "๐์ ๋๊ฐ์ ํจ์์์ ~" ๋ผ๊ณ ํ๋จํ๊ณ ๋ฆฌ๋ ๋๋ง์ ๋ง์์ค ๊ฒ ๊ฐ์ง๋ง ์ฝ์์ฐฝ์ ๋ณด๋ ๊ทธ๋ ๊ฒ ์๋ํ์ง ์๋๋ค.
๊ทธ ์ด์ ๋, memo๋ก ๊ฐ์ผ ์ปดํฌ๋ํธ์์ ์๊ธฐ๊ฐ ๊ฐ์ง๊ณ ์๋ clickHandler๋ฅผ ๊ณ์ ๋น๊ต๋ฅผ ํ๊ฒ ์ง๋ง, App์ด ๋ฆฌ๋ ๋๋ง ๋ ๋๋ง๋ค ์๋ก์ด clickHandler๋ฅผ ์์ฑ์ํค๊ณ ๋ด๋ ค์ฃผ๊ธฐ ๋๋ฌธ์, Child๊ฐ ๊ณ์ ๋ฆฌ๋ ๋๋ง์ด ๋๋ค
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ useCallback์ผ๋ก ํจ์๋ฅผ ๊ฐ์ผ๋ค.
์์์ ํ์ธํด๋ณธ Profiler์ ํตํด ์ด๋ค์์ผ๋ก ๋ฆฌ๋ ๋๋ง์ด ๋๋์ง ํ์ธํด๋ด ์๋ค.
Why did this render?์ ๋ณด๋ฉด Props changed๋ผ๋ฉฐ "clickHandler์ ๋ณ๊ฒฝ์ด ์๊ฒผ๊ธฐ์ Child๊ฐ ๋ฆฌ๋ ๋๋ง ๋๋ค~" ๋ผ๊ณ ์๋ ค์ฃผ๊ณ ์์ต๋๋ค.
๐ ์ฐธ๊ณ : ์์ ๋์ค์ ์ ๋๋ ์ Why did this render์ด ์๋จ์ง? ๋ผ๊ณ ์๊ฐํ๋๋ฐ ๋ฐ๋ก ์ค์ ํ๋ฉด ๋ฉ๋๋ค~
ํฑ๋๋ฐํด ์์ด์ฝ์ ๋๋ฌ์ Profilerํญ์ ๋ค์ด๊ฐ๊ณ , ์๋์ ํ์ํ ์ฒดํฌ๋ฅผ ํ์ฑํ ์ํค๋ฉด ๋ฉ๋๋ค!
๋ค์ ์ฝ๋๋ก ๋์๊ฐ์, ์ด์ useCallback์ ์ ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
import React, { useCallback, useState } from "react";
import "./styles.css";
export default function App() {
console.log("App");
const [, setState] = useState();
const clickHandler = useCallback(() => {
console.log("Clicked!");
}, []);
return (
<div className="App">
<h1>react performance</h1>
<button onClick={() => setState(Math.random())}>๋ถ๋ชจ๊ฐ์ ๋ ๋๋ง</button>
<MemoChild clickHandler={clickHandler} data="str" />
</div>
);
}
function Child(props) {
console.log("Child");
return <div>{props.data}</div>;
}
export const MemoChild = React.memo(Child);
๋ฆฌ๋ ๋๋ง์ด ๋์ง ์์ต๋๋ค ~ ๐๐๐