23.05.04 TIL ๐Ÿป

์ƒค์ด๋‹ˆยท2023๋…„ 5์›” 4์ผ
0

learned.log

๋ชฉ๋ก ๋ณด๊ธฐ
44/46

์˜ค๋Š˜์˜ ๋‚˜๋Š” ๋ฌด์—‡์„ ์ƒˆ๋กญ๊ฒŒ ๋ฐฐ์› ๋‚˜์š”?

[1] React.memo


React๋Š” ๊ณ ์ฐจ ์ปดํผ๋„ŒํŠธ(Higher Order Component, HOC)ย React.memo()๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ์ด์ง•(Memoizing)ํ•จ์œผ๋กœ์จ, ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ด๋‹ค.


const App = () => {
	return (
		<div>์•ˆ๋…•ํ•˜์„ธ์š”</div>
		<div>์•ˆ๋…•ํžˆ๊ณ„์„ธ์š”</div>
	)
}

export default React.memo(App) // ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑ ํ›„ ์•„๋ž˜์— React.memo๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ Higher Order Component, HOC


  • ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„ ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
  • ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ๋Š” with์ปดํฌ๋„ŒํŠธ๋กœ ๋ช…๋ช…ํ•œ๋‹ค.
  • App.jsx
import './App.css';
import User from './components/User';
import withCurrent from './components/withCurrent';

const CurrentUser = withCurrent(User); // withCurrent ์ปดํฌ๋„ŒํŠธ์— User ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งค๊ฒจ๋ณ€์ˆ˜๋กœ
																			 // ์‚ฌ์šฉํ•จ
function App() {
  return (
    <div>
      <CurrentUser userName="uey" />
    </div>
  );
}

export default App;
  • withCurrent.jsx
import React, { useEffect, useState } from 'react';

function withCurrent(Component) { // user ์ปดํฌ๋„ŒํŠธ
  const NewComponent = ({ userName, props }) => {
    const [user, setUser] = useState('');

    useEffect(() => {
      let timer = setTimeout(() => {
        setUser(userName);

        clearTimeout(timer);
      }, 1000);
    });

    if (!user) return 'Loading';

    return <Component {...props} user={user} />; // user ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ
  };

  return NewComponent;
}

export default withCurrent;
  • User.jsx
import React from 'react';

function User({ user }) { // withCurrent๋กœ๋ถ€ํ„ฐ์˜จ props
  return (
    <div>
      <strong>{user}</strong>
    </div>
  );
}

export default User;

React๋Š” ๋จผ์ € ์ปดํผ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง(rendering) ํ•œ ๋’ค, ์ด์ „ ๋ Œ๋”๋œ ๊ฒฐ๊ณผ์™€ ๋น„๊ตํ•˜์—ฌ DOM ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค. ๋งŒ์•ฝ ๋ Œ๋” ๊ฒฐ๊ณผ๊ฐ€ ์ด์ „๊ณผ ๋‹ค๋ฅด๋‹ค๋ฉด, React๋Š” DOM์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

๋‹ค์Œ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ์™€ ์ด์ „ ๊ฒฐ๊ณผ์˜ ๋น„๊ต๋Š” ๋น ๋ฅด๋‹ค. ํ•˜์ง€๋งŒ ์–ด๋–ค ์ƒํ™ฉ์—์„œ๋Š” ์ด ๊ณผ์ •์˜ ์†๋„๋ฅผ ์ข€ ๋” ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.

์ปดํผ๋„ŒํŠธ๊ฐ€ย React.memo()๋กœ ๋ž˜ํ•‘ ๋  ๋•Œ, React๋Š” ์ปดํผ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ์ด์ง•(Memoizing)ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚  ๋•Œย props๊ฐ€ ๊ฐ™๋‹ค๋ฉด, React๋Š” ๋ฉ”๋ชจ์ด์ง•(Memoizing)๋œ ๋‚ด์šฉ์„ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

props ๋™๋“ฑ ๋น„๊ต ์ปค์Šคํ…€ ๋งˆ์ด์ง•


React.memo()๋Š” props ํ˜น์€ props ๊ฐ์ฒด๋ฅผ ๋น„๊ตํ•  ๋•Œ ์–•์€ ๋น„๊ต๋ฅผ ํ•œ๋‹ค. โ† depth 1๋งŒ ํŒ๋‹จ

๋น„๊ต ๋ฐฉ์‹์„ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋น„๊ตํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋„˜๊ฒจ์ฃผ๋ฉด ๋œ๋‹ค.
React.memo(Component, [areEqual(prevProps, nextProps)]);

function moviePropsAreEqual(prevData, nextData) {
  return (
    prevData.title === nextData.title &&
    prevData.releaseDate === nextData.releaseDate
  );
}

const MemoizedMovie2 = React.memo(Movie, moviePropsAreEqual);
  • moviePropsAreEqual()ย ํ•จ์ˆ˜๋Š” ์ด์ „ย props์™€ ํ˜„์žฌย props๊ฐ€ ๊ฐ™๋‹ค๋ฉดย true๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ด๋‹ค.
    true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์ด์ „์— ๋ฉ”๋ชจ์ด์ง• ๋œ ๋‚ด์šฉ์„ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

React.memo() ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ


  • React.memo()๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๊ฐ€์žฅ ์ข‹์€ ์ผ€์ด์Šค๋Š” ํ•จ์ˆ˜ํ˜• ์ปดํผ๋„ŒํŠธ๊ฐ€ ๊ฐ™์€ย props๋กœ ์ž์ฃผ ๋ Œ๋”๋ง ๋ ๊ฑฐ๋ผ ์˜ˆ์ƒ๋  ๋•Œ์ด๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ™์€ props๋กœ ์ž์ฃผ ๋ Œ๋”๋ง๋˜๊ฑฐ๋‚˜, ๋ฌด๊ฒ๊ณ  ๋น„์šฉ์ด ํฐ ์—ฐ์‚ฐ์ด ์žˆ๋Š” ๊ฒฝ์šฐ,ย React.memo()๋กœ ์ปดํผ๋„ŒํŠธ๋ฅผ ๋ž˜ํ•‘ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
  • React.memo() ์‚ฌ์šฉํ•  ๋•Œ๋Š” useCallback, useMemo๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ ํ™”๋ฅผ ์ง„ํ–‰ํ•ด์•ผํ•œ๋‹ค.
    ๋ถ€๋ชจ๋กœ๋ถ€ํ„ฐ props๋ฅผ ํ†ตํ•ด ๋ฐ›์•„์˜จ ํ•จ์ˆ˜๋Š” ๋งค ๋ Œ๋”๋ง๋งˆ๋‹ค ์ƒˆ ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋˜๊ธฐ ๋•Œ๋ฌธ์— React.memo๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๋ฆฌ์•กํŠธ๊ฐ€ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ด๋•Œ useCallback์„ ์ด์šฉํ•˜๋ฉด ๊ฐ™์€ ํ•จ์ˆ˜์ž„์„ ๋ณด์žฅํ•˜์—ฌReact.memo๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • useMemo ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๊ณ„์‚ฐํ•œ ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ, ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. useMemo๋Š” ์ฃผ๋กœ ๊ณ„์‚ฐ์ด ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

react.memo()๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ


  • props๊ฐ€ ์ž์ฃผ ๋ณ€ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ React.memo()๋กœ ๋งคํ•‘ํ• ์ง€๋ผ๋„ 2๊ฐ€์ง€ ๊ณผ์ •์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  1. ์ด์ „ย props์™€ ๋‹ค์Œย props์˜ ๋™๋“ฑ ๋น„๊ต๋ฅผ ์œ„ํ•ด ๋น„๊ต ํ•จ์ˆ˜๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  2. ๋น„๊ต ํ•จ์ˆ˜๋Š” ๊ฑฐ์˜ ํ•ญ์ƒย false๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, React๋Š” ์ด์ „ ๋ Œ๋”๋ง ๋‚ด์šฉ๊ณผ ๋‹ค์Œ ๋ Œ๋”๋ง ๋‚ด์šฉ์„ ๋น„๊ตํ•  ๊ฒƒ์ด๋‹ค.
  3. ์ด๋Ÿฐ ๋น„๊ต๊ณผ์ •์€ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ React.memo๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ณต๋ถ€ํ•˜๋ฉด์„œ ์–ด๋–ค ์–ด๋ ค์›€์ด ์žˆ์—ˆ๋‚˜์š”?

TO DO List state ๊ด€๋ฆฌ

๋„ˆ์–ด๋ฌด.. ํž˜๋“ค์—ˆ๋‹ค. state๊ฐ€ ๋งŽ์œผ๋‹ˆ๊นŒ ๋„ˆ๋ฌด ๊ผฌ์ด๊ณ .. ์ง€๊ธˆ์€ ๋„ˆ๋ฌด ์กธ๋ ค์„œ ๋‚ด์ผ ๋” ์ƒ์„ธํžˆ ์ •๋ฆฌํ•  ์˜ˆ์ •์ด๋‹ค.

  1. Calendar์— ๋„˜๊ฒจ์ฃผ๋Š” selectedDate undefined ์ด์Šˆ
  2. TodoItem์œผ๋กœ ๋„˜๊ฒจ์ฃผ๊ธฐ ์œ„ํ•ด์„  props drilling์œผ๋กœ TodoList์—๋„ ๋„˜๊ฒจ์ค˜์•ผํ•จ.
  3. ๋ชจ๋“  ๋ฐ์ดํ„ฐ์˜ ํ˜•์‹์ด ์ฒ˜์Œ์— undefined๋ฉด ๊ทธ์— ๋Œ€ํ•œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ•จ.
  4. todoList set์— ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ, id๊ฐ€ ์ค‘๋ณต๋˜๋Š” ์ด์Šˆ
    • useRef๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•˜๋ ค๋‹ค ๋ณด๋‹ˆ..

๋‚ด์ผ์˜ ๋‚˜๋Š” ๋ฌด์—‡์„ ๊ณต๋ถ€ํ•ด์•ผ ํ• ๊นŒ์š”?

ํ† ๋‹ˆ์™€ ๋ถˆํƒ€๋Š” ํŽ˜์–ดํ”„๋กœ๊ทธ๋ž˜๋ฐ.. ์ œ๋ฐœ ๋๋‚ผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์„ธ์š” ์—‰์—‰๐Ÿ˜ญ๐Ÿ˜ญ

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