React - The Complete Guide

Section 12: React - Behind the Scenes - How React Works

olivia_yj 2022. 11. 29. 07:43

The goals

๐Ÿ’ช๐ŸปHow Does React Work Behind The Scenes?

โœŒ๐ŸปUnderstanding the Virtual DOM & DOM Updates

๐Ÿ‘๐ŸปUnderstanding State & State Updates

 

 

 

 

useMemo ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ์‚ฐํ•œ ๊ฐ’ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ

์ด๋ฒˆ์—๋Š” ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•˜์—ฌ ์—ฐ์‚ฐ๋œ ๊ฐ’์„ useMemo๋ผ๋Š” Hook ์„ ์‚ฌ์šฉํ•˜์—ฌ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

App ์ปดํฌ๋„ŒํŠธ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด countActiveUsers ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ, active ๊ฐ’์ด true ์ธ ์‚ฌ์šฉ์ž์˜ ์ˆ˜๋ฅผ ์„ธ์–ด์„œ ํ™”๋ฉด์— ๋ Œ๋”๋ง์„ ํ•ด๋ณด์„ธ์š”.

App.js

import React, { useRef, useState } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function countActiveUsers(users) {
  console.log('ํ™œ์„ฑ ์‚ฌ์šฉ์ž ์ˆ˜๋ฅผ ์„ธ๋Š”์ค‘...');
  return users.filter(user => user.active).length;
}

function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email } = inputs;
  const onChange = e => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com',
      active: true
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com',
      active: false
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com',
      active: false
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

  const onRemove = id => {
    // user.id ๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ์›์†Œ๋งŒ ์ถ”์ถœํ•ด์„œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ฌ
    // = user.id ๊ฐ€ id ์ธ ๊ฒƒ์„ ์ œ๊ฑฐํ•จ
    setUsers(users.filter(user => user.id !== id));
  };
  const onToggle = id => {
    setUsers(
      users.map(user =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  };
  const count = countActiveUsers(users);
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle} />
      <div>ํ™œ์„ฑ์‚ฌ์šฉ์ž ์ˆ˜ : {count}</div>
    </>
  );
}

export default App;

countActiveUsers ํ•จ์ˆ˜์—์„œ ์ฝ˜์†”์— ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋„๋ก ํ•œ ์ด์œ ๋Š”, ์ด ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ ๋•Œ๋งˆ๋‹ค ์šฐ๋ฆฌ๊ฐ€ ์•Œ์ˆ˜์žˆ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.

๊ตฌํ˜„์„ ๋งˆ์น˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜ํƒ€๋‚ ํ…๋ฐ์š”.

๋‹ค๋ฅธ ๊ณ„์ •๋ช…์„ ๋ˆŒ๋Ÿฌ์„œ ์ดˆ๋ก์ƒ‰์œผ๋กœ ๋งŒ๋“ค๋ฉด ํ™œ์„ฑ ์‚ฌ์šฉ์ž ์ˆ˜ ๋˜ํ•œ ์—…๋ฐ์ดํŠธ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, ์—ฌ๊ธฐ์„œ ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ์  ๋ฌธ์ œ๊ฐ€ ํ•œ๊ฐ€์ง€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ, input ์˜ ๊ฐ’์„ ๋ฐ”๊ฟ€๋•Œ์—๋„ countActiveUsers ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

ํ™œ์„ฑ ์‚ฌ์šฉ์ž ์ˆ˜๋ฅผ ์„ธ๋Š”๊ฑด, users ์— ๋ณ€ํ™”๊ฐ€ ์žˆ์„๋•Œ๋งŒ ์„ธ์•ผ๋˜๋Š”๊ฑด๋ฐ, input ๊ฐ’์ด ๋ฐ”๋€” ๋•Œ์—๋„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋ฏ€๋กœ ์ด๋ ‡๊ฒŒ ๋ถˆํ•„์š”ํ• ๋•Œ์—๋„ ํ˜ธ์ถœํ•˜์—ฌ์„œ ์ž์›์ด ๋‚ญ๋น„๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—๋Š” useMemo ๋ผ๋Š” Hook ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์„ ์ตœ์ ํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Memo ๋Š” "memoized" ๋ฅผ ์˜๋ฏธํ•˜๋Š”๋ฐ, ์ด๋Š”, ์ด์ „์— ๊ณ„์‚ฐ ํ•œ ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•œ๋ฒˆ ์‚ฌ์šฉํ•ด๋ณผ๊นŒ์š”?

App.js

import React, { useRef, useState, useMemo } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function countActiveUsers(users) {
  console.log('ํ™œ์„ฑ ์‚ฌ์šฉ์ž ์ˆ˜๋ฅผ ์„ธ๋Š”์ค‘...');
  return users.filter(user => user.active).length;
}

function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email } = inputs;
  const onChange = e => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com',
      active: true
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com',
      active: false
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com',
      active: false
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

  const onRemove = id => {
    // user.id ๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ์›์†Œ๋งŒ ์ถ”์ถœํ•ด์„œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ฌ
    // = user.id ๊ฐ€ id ์ธ ๊ฒƒ์„ ์ œ๊ฑฐํ•จ
    setUsers(users.filter(user => user.id !== id));
  };
  const onToggle = id => {
    setUsers(
      users.map(user =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  };
  const count = useMemo(() => countActiveUsers(users), [users]);
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle} />
      <div>ํ™œ์„ฑ์‚ฌ์šฉ์ž ์ˆ˜ : {count}</div>
    </>
  );
}

export default App;

useMemo ์˜ ์ฒซ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” ์–ด๋–ป๊ฒŒ ์—ฐ์‚ฐํ• ์ง€ ์ •์˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋˜๊ณ  ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” deps ๋ฐฐ์—ด์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋˜๋Š”๋ฐ, ์ด ๋ฐฐ์—ด ์•ˆ์— ๋„ฃ์€ ๋‚ด์šฉ์ด ๋ฐ”๋€Œ๋ฉด, ์šฐ๋ฆฌ๊ฐ€ ๋“ฑ๋กํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๊ฐ’์„ ์—ฐ์‚ฐํ•ด์ฃผ๊ณ , ๋งŒ์•ฝ์— ๋‚ด์šฉ์ด ๋ฐ”๋€Œ์ง€ ์•Š์•˜๋‹ค๋ฉด ์ด์ „์— ์—ฐ์‚ฐํ•œ ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํ•œ๋ฒˆ ๊ณ„์ •๋ช…๋“ค์„ ํด๋ฆญ๋„ ํ•ด๋ณด๊ณ , input ์„ ์ˆ˜์ •๋„ ํ•ด๋ณด์„ธ์š”.

๊ทธ๋Ÿผ ์ตœ์ ํ™”์™€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์ ˆ์•ฝํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ์•ˆ์œผ๋กœ useMemo๋ฅผ ์•„๋ฌด๊ณณ์—๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ?

๋‹ต์€ nej

์ตœ์ ํ™”๋ฅผ ํ•ด์ฃผ๋Š” ๋Œ€์‹ ์— ์–ด๋А์ •๋„์˜ ๋น„์šฉ์ด ์š”๊ตฌ๋จ.

๊ทธ ๋น„์šฉ์ด๋ผํ•˜๋ฉด ์ด์ „ props๊ฐ’์„ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ๊ณผ ๋น„๊ต๋ฅผ ํ•˜๋Š” ๋™์ž‘์„ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ!

 

 

useCallback ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ

useCallback ์€ ์šฐ๋ฆฌ๊ฐ€ ์ง€๋‚œ ์‹œ๊ฐ„์— ๋ฐฐ์› ๋˜ useMemo ์™€ ๋น„์Šทํ•œ Hook ์ž…๋‹ˆ๋‹ค.

useMemo ๋Š” ํŠน์ • ๊ฒฐ๊ณผ๊ฐ’์„ ์žฌ์‚ฌ์šฉ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ˜๋ฉด, useCallback ์€ ํŠน์ • ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์žฌ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด์ „์— App.js ์—์„œ ๊ตฌํ˜„ํ–ˆ์—ˆ๋˜ onCreate, onRemove, onToggle ํ•จ์ˆ˜๋ฅผ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค.

const onCreate = () => {
  const user = {
    id: nextId.current,
    username,
    email
  };
  setUsers(users.concat(user));

  setInputs({
    username: '',
    email: ''
  });
  nextId.current += 1;
};

const onRemove = id => {
  // user.id ๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ์›์†Œ๋งŒ ์ถ”์ถœํ•ด์„œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ฌ
  // = user.id ๊ฐ€ id ์ธ ๊ฒƒ์„ ์ œ๊ฑฐํ•จ
  setUsers(users.filter(user => user.id !== id));
};
const onToggle = id => {
  setUsers(
    users.map(user =>
      user.id === id ? { ...user, active: !user.active } : user
    )
  );
};

์ด ํ•จ์ˆ˜๋“ค์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋  ๋•Œ ๋งˆ๋‹ค ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฒƒ ์ž์ฒด๋Š” ์‚ฌ์‹ค ๋ฉ”๋ชจ๋ฆฌ๋„, CPU ๋„ ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŽ์ด ์ฐจ์ง€ ํ•˜๋Š” ์ž‘์—…์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ ์„ ์–ธํ•œ๋‹ค๊ณ  ํ•ด์„œ ๊ทธ ์ž์ฒด ๋งŒ์œผ๋กœ ํฐ ๋ถ€ํ•˜๊ฐ€ ์ƒ๊ธธ์ผ์€ ์—†์ง€๋งŒ, ํ•œ๋ฒˆ ๋งŒ๋“  ํ•จ์ˆ˜๋ฅผ ํ•„์š”ํ• ๋•Œ๋งŒ ์ƒˆ๋กœ ๋งŒ๋“ค๊ณ  ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์—ฌ์ „ํžˆ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ์ด์œ ๋Š”, ์šฐ๋ฆฌ๊ฐ€ ๋‚˜์ค‘์— ์ปดํฌ๋„ŒํŠธ์—์„œ props ๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š์•˜์œผ๋ฉด Virtual DOM ์— ์ƒˆ๋กœ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ ์กฐ์ฐจ ํ•˜์ง€ ์•Š๊ณ  ์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฐ๊ณผ๋ฌผ์„ ์žฌ์‚ฌ์šฉ ํ•˜๋Š” ์ตœ์ ํ™” ์ž‘์—…์„ ํ• ๊ฑด๋ฐ์š”, ์ด ์ž‘์—…์„ ํ•˜๋ ค๋ฉด, ํ•จ์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์ด ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.

useCallback ์€ ์ด๋Ÿฐ์‹์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

App.js

import React, { useRef, useState, useMemo, useCallback } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function countActiveUsers(users) {
  console.log('ํ™œ์„ฑ ์‚ฌ์šฉ์ž ์ˆ˜๋ฅผ ์„ธ๋Š”์ค‘...');
  return users.filter(user => user.active).length;
}

function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email } = inputs;
  const onChange = useCallback(
    e => {
      const { name, value } = e.target;
      setInputs({
        ...inputs,
        [name]: value
      });
    },
    [inputs]
  );
  const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com',
      active: true
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com',
      active: false
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com',
      active: false
    }
  ]);

  const nextId = useRef(4);
  const onCreate = useCallback(() => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  }, [users, username, email]);

  const onRemove = useCallback(
    id => {
      // user.id ๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ์›์†Œ๋งŒ ์ถ”์ถœํ•ด์„œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ฌ
      // = user.id ๊ฐ€ id ์ธ ๊ฒƒ์„ ์ œ๊ฑฐํ•จ
      setUsers(users.filter(user => user.id !== id));
    },
    [users]
  );
  const onToggle = useCallback(
    id => {
      setUsers(
        users.map(user =>
          user.id === id ? { ...user, active: !user.active } : user
        )
      );
    },
    [users]
  );
  const count = useMemo(() => countActiveUsers(users), [users]);
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle} />
      <div>ํ™œ์„ฑ์‚ฌ์šฉ์ž ์ˆ˜ : {count}</div>
    </>
  );
}

export default App;

์ฃผ์˜ ํ•˜์‹ค ์ ์€, ํ•จ์ˆ˜ ์•ˆ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ƒํƒœ ํ˜น์€ props ๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ผญ, deps ๋ฐฐ์—ด์•ˆ์— ํฌํ•จ์‹œ์ผœ์•ผ ๋œ๋‹ค๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ์— deps ๋ฐฐ์—ด ์•ˆ์— ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ’์„ ๋„ฃ์ง€ ์•Š๊ฒŒ ๋œ๋‹ค๋ฉด, ํ•จ์ˆ˜ ๋‚ด์—์„œ ํ•ด๋‹น ๊ฐ’๋“ค์„ ์ฐธ์กฐํ• ๋•Œ ๊ฐ€์žฅ ์ตœ์‹  ๊ฐ’์„ ์ฐธ์กฐ ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๋ณด์žฅ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. props ๋กœ ๋ฐ›์•„์˜จ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค๋ฉด, ์ด ๋˜ํ•œ deps ์— ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•ด์š”.

์‚ฌ์‹ค, useCallback ์€ useMemo ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ, ํ•จ์ˆ˜๋ฅผ ์œ„ํ•ด์„œ ์‚ฌ์šฉ ํ•  ๋•Œ ๋”์šฑ ํŽธํ•˜๊ฒŒ ํ•ด์ค€ ๊ฒƒ ๋ฟ์ด์ง€์š”. ์ด๋Ÿฐ์‹์œผ๋กœ๋„ ํ‘œํ˜„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const onToggle = useMemo(
  () => () => {
    /* ... */
  },
  [users]
);

useCallback ์„ ์‚ฌ์šฉ ํ•จ์œผ๋กœ์จ, ๋ฐ”๋กœ ์ด๋ค„๋‚ผ์ˆ˜ ์žˆ๋Š” ๋ˆˆ์— ๋„๋Š” ์ตœ์ ํ™”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜์ƒ์—์„œ, ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ์ตœ์ ํ™” ์ž‘์—…์„ ํ•ด์ฃผ์–ด์•ผ๋งŒ ์„ฑ๋Šฅ์ด ์ตœ์ ํ™”๋˜๋Š”๋ฐ์š”, ๊ทธ ์ „์—, ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ React DevTools ๋ผ๋Š” ๊ฒƒ์„ ์†Œ๊ฐœ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ์„ , ๊ตฌ๊ธ€์— React DevTools ๋ฅผ ๊ฒ€์ƒ‰ํ•ด์„œ ํฌ๋กฌ ์›น์Šคํ† ์–ด์— ๋“ค์–ด๊ฐ„๋’ค, ํฌ๋กฌ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์„ ์„ค์น˜ํ•ด์ฃผ์„ธ์š”. ๋งํฌ

์„ค์น˜๋ฅผ ํ•˜๊ณ  ๋‚˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด React ํƒญ์ด ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์— ๋œน๋‹ˆ๋‹ค. ํ†ฑ๋‹ˆ๋ฐ”ํ€ด ์•„์ด์ฝ˜์„ ๋ˆ„๋ฅด๊ณ , 'Highlight Updates' ๋ฅผ ์ฒดํฌํ•ด์ฃผ์„ธ์š”.

์ด ์†์„ฑ์„ ํ‚ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฆฌ๋ Œ๋”๋ง ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์— ์‚ฌ๊ฐํ˜• ํ˜•ํƒœ๋กœ ํ•˜์ด๋ผ์ดํŠธ๋˜์–ด ๋ณด์—ฌ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ ๋ณด๋ฉด, input ์ด ๋ฐ”๋€” ๋•Œ์—๋„ UserList ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง์ด ๋˜๊ณ  ์žˆ์ง€์š”?

๋‹ค์Œ ์˜์ƒ์—์„œ๋Š” ์ด ๋ฆฌ๋ Œ๋”๋ง์„ ๋ง‰์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

Summary 1.

React -> usually we work with Functional Component which returns JSX syntax

Props-> we can give props to each component 

Whenever we change the state of component, the componenet will be re-evaluated -> the component function executes again

React just brings the latest screen shot and compare it to previous one and if there is some differeces then React deliver it to React DOM because we are using React DOM to render the files.

When we re-evaluate, we run the codes again at the same time functions also + output JSX syntax also.

So to prevent unneccessory re-execution of code, we can use 'React.memo'

but some case that we set the relative value with using '=' then it can't be controlled by 'React.memo', then we can use 'useCallback'

 

Then every time if the App functions runs again whenever the state changes, doesn't this mean that we will re-initialize our code? and re-execute 'useState' over and over again?

 

 

 

 

Sources

https://react.vlpt.us/basic/17-useMemo.html

 

17. useMemo ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ์‚ฐํ•œ ๊ฐ’ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ · GitBook

17. useMemo ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ์‚ฐํ•œ ๊ฐ’ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์ด๋ฒˆ์—๋Š” ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•˜์—ฌ ์—ฐ์‚ฐ๋œ ๊ฐ’์„ useMemo๋ผ๋Š” Hook ์„ ์‚ฌ์šฉํ•˜์—ฌ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. App ์ปดํฌ๋„ŒํŠธ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด co

react.vlpt.us

https://academind.com/tutorials/reference-vs-primitive-values

 

Reference vs Primitive Values

Learn why most people copy objects and arrays in JavaScript incorrectly. And why you won't make that mistake!

academind.com

https://velog.io/@ggong/useState-Hook%EA%B3%BC-%ED%81%B4%EB%A1%9C%EC%A0%80

 

useState Hook๊ณผ ํด๋กœ์ €

์ „์— ๊ธฐ์ˆ  ๋ฉด์ ‘์„ ๋ณด๋ฉด์„œ "React hook์—์„œ ํด๋กœ์ €๊ฐ€ ์–ด๋–ป๊ฒŒ ์“ฐ์ด๋Š”์ง€ ์„ค๋ช…ํ•ด๋ณด์„ธ์š”" ๋ผ๋Š” ์งˆ๋ฌธ์„ ๋ฐ›์€ ์ ์ด ์žˆ์—ˆ๋‹ค. ๋‚˜๋ฆ„ ๋ฆฌ์•กํŠธ๋ฅผ ์˜ค๋ž˜ ์ผ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ํด๋กœ์ €์— ๋Œ€ํ•ด์„œ๋„ ๋ฐฉ๊ธˆ ์„ค๋ช…ํ–ˆ๋Š”๋ฐ..

velog.io

https://yeoulcoding.tistory.com/149#recentEntries

 

[React] ํด๋กœ์ €์™€ useState Hooks

Overview React Hooks๋Š” React Functional Component(ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ)์—์„œ ์ƒํƒœ๊ด€๋ฆฌ ๋ฐ ์ปดํฌ๋„ŒํŠธ ์ƒ๋ช…์ฃผ๊ธฐ API(Lifecycle API) ๋“ฑ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์ง€์›ํ–ˆ๋˜ ๊ธฐ๋Šฅ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. ํ•จ์ˆ˜ํ˜•

yeoulcoding.me