๐Ÿ’ช React. Hooks w/ ์ง„์œ ๋ฆผ ๋‹˜

[meษช]ยท2022๋…„ 2์›” 2์ผ
0

1-3. Today I Learned. React.js

๋ชฉ๋ก ๋ณด๊ธฐ
9/9
post-thumbnail

Preface

๐Ÿ“Œ ๊ฐœ๋ฐœ ๊ณต๋ถ€ 6๊ฐœ์›” ์ฐจ์ธ to-be ๊ฐœ๋ฐœ์ž์˜ ์ž์Šต blog๐Ÿ™‚๏พ MMM DD ~ DD, YYYY

ํ˜„์žฌ ์ƒํƒœ
HTML๋ถ€ํ„ฐ React๊นŒ์ง€ ๊ฐ•์˜๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ๋“ค์—ˆ๋Š”๋ฐ, ๊ทธ ์ค‘ ๋‚˜์—๊ฒ ๋งˆ์น˜ phase 1์˜ ๋ํŒ์™•๊ฐ™์€ React๋ฅผ ์•„์ฃผ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด ์ฃผ๋Š” ๊ฐ•์˜๋ฅผ ์ฐพ์€ ๊ฒƒ ๊ฐ™์•„ remindํ•  ๊ฒธ ์ˆ˜๊ฐ•ํ•ด๋ณด์•˜๋‹ค.


โž• afterthought

๊ฐ•์˜ ๋‚ด์šฉ ์ค‘ "'ํ•จ์ˆ˜๋ž‘ component๋ž‘ ๋ฌด์Šจ ์ƒ๊ด€์ด์ง€?'๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹ค ์ˆ˜๋„ ์žˆ๋Š”๋ฐ์š”."๋ผ๋Š” ๋ถ€๋ถ„์— ๊ฐ๋™(?)...!
์ฒ˜์Œ React๋ฅผ ๋จธ๋ฆฌ์— ๋„ฃ์„ ๋•Œ (๋ฐฐ์šด ๊ฑฐ ์•„๋‹ˆ๊ณ  ๋„ฃ์–ด์•ผ ํ–ˆ์œผ๋‹ˆ...ลโ–ฝล) ์•ž์„œ ๋ฐฐ์šด JS๋‚˜ DOM ์ด๋Ÿฐ ๊ฒƒ๋“ค์ด ์ •๋ฆฌ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค ๋ณด๋‹ˆ ์•Œ๊ณ  ๋ณด๋ฉด ๋ณด์ด๋Š” ๊ทธ ์—ฐ๊ฒฐ๊ณ ๋ฆฌ๋ฅผ ๊นจ๋‹ซ์ง€ ๋ชปํ–ˆ๋‹ค.
'ํ•จ์ˆ˜๋กœ ์–ด๋–ป๊ฒŒ ๋™์ž‘์„ ๋งŒ๋“ ๋‹ค๋Š” ๊ฑด์ง€' ํ•œ๋™์•ˆ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ด ํž˜๋“ค์—ˆ๋˜ ๋‚ ๋“ค์ด ๋– ์˜ค๋ฅธ๋‹ค.

P.S. ์ง„์œ ๋ฆผ ๋‹˜์€ ๊ฐ•์˜ ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์—์„œ CRA๋ฅผ ์‚ฌ์šฉํ•˜์‹ ๋‹ค.

link to ๐Ÿ›ผ





โ€ป ๋ชฉํ‘œ : body์— ๋™์ ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ

1. ๊ธฐ๋ณธ ๊ฐœ๋…

1) ๋™์ ์ธ ๋™์ž‘์„ React๊ฐ€ ์•„๋‹Œ JavaScript๋กœ๋งŒ ํ•  ๋•Œ

// ๐ŸŽต ๊ณ ์–‘์ด ์‚ฌ์ง„์— ์žˆ๋Š” heart ๋ชจ์–‘ button์„ ๋ˆ„๋ฅด๋ฉด ์ด button์ด ๋‹ค๋ฅธ ๋ชจ์–‘์œผ๋กœ ๋ฐ”๋€Œ๊ณ  <li /> ํ•˜์œ„์— ํ•ด๋‹นํ•˜๋Š” ๊ณ ์–‘์ด ์‚ฌ์ง„์„ ์ถ”๊ฐ€ํ•˜๊ธฐ
// (1)
<body>
  <script>
  // STEP 1. ์ข‹์•„์š” button ์ฐพ๊ธฐ
  const likeButton = document.querySelector(".main-card button");
    // STEP 2. ์ข‹์•„์š” button์— click event ๋ถ€์—ฌํ•˜๊ธฐ
    likeButton.addEventListener("click", function () {
      // STEP 3. ์ข‹์•„์š” button์„ clickํ–ˆ์„ ๋•Œ button ๋ณ€๊ฒฝํ•˜๊ธฐ
      likeButton.innerHTML = "๐Ÿ˜";
      // STEP 4. ์ข‹์•„์š” ํ•œ ๊ณ ์–‘์ด๋ฅผ ์ถ”๊ฐ€ํ•  ๊ณณ ์ฐพ๊ธฐ
      const favorites = document.querySelector(".favorites");
      // STEP 5. ์ƒˆ๋กœ์šด ๊ณ ์–‘์ด ์‚ฌ์ง„ ๋งŒ๋“ค๊ธฐ = <img src="">
      const newFavoriteImage = document.createElement("img");
      newFavoriteImage.src = "https://cataas.com/cat/60b73094e04e18001194a309/says/react";
      // STEP 6. ๊ณ ์–‘์ด ์‚ฌ์ง„์„ ๊ฐ์‹ธ๋Š” li tag ๋„ฃ๊ธฐ = <li> <img> </li>
      const li = document.createElement('li');
      // STEP 7. li tag์— ๊ณ ์–‘์ด ์‚ฌ์ง„ ๋„ฃ๊ธฐ
      li.appendChild(newFavoriteImage);
      // STEP 8. ์ข‹์•„์š” ํ•œ ๊ณ ์–‘์ด๋ฅผ ์ถ”๊ฐ€ํ•  ๊ณณ์— ๋ฐฉ๊ธˆ ๋งŒ๋“  ์š”์†Œ๋ฅผ ๋„ฃ๊ธฐ
      favorites.appendChild(li);
    });
  </ script>
</body>

JavaScript์œผ๋กœ ๊ธฐ๋Šฅ๋„ ๊ตฌํ˜„ํ•˜๊ณ  ๋‚ด์šฉ๋„ ๊ทธ๋ ค๋‚ด์•ผ ํ•˜๋Š”๋ฐ ๊ทธ ๋ฌธ๋ฒ•์ด ๋ณต์žกํ•˜๊ณ  ๋น„ํšจ์œจ์ ์ด๋‹ค.

2) ๋™์ ์ธ ๋™์ž‘์„ React๋กœ ํ•  ๋•Œ

// ๐ŸŽต ๊ณ ์–‘์ด ์‚ฌ์ง„์— ์žˆ๋Š” heart ๋ชจ์–‘ button์„ ๋ˆ„๋ฅด๋ฉด ์ด button์ด ๋‹ค๋ฅธ ๋ชจ์–‘์œผ๋กœ ๋ฐ”๋€Œ๊ณ  <li /> ํ•˜์œ„์— ํ•ด๋‹นํ•˜๋Š” ๊ณ ์–‘์ด ์‚ฌ์ง„์„ ์ถ”๊ฐ€ํ•˜๊ธฐ
// (2)
<body>
  // STEP 2. ๊ณ ์–‘์ด ์‚ฌ์ง„์„ ๋„ฃ์–ด์ค„ ๊ณต๊ฐ„ ๋งŒ๋“ค๊ธฐ
  <div id="app"></div>

  <script>
    // STEP 1. <li / >๋กœ ๊ณ ์–‘์ด ์‚ฌ์ง„์„ ๊ฐ์‹ธ๊ธฐ
    const catItem = (
       <li>
          <img src="https://cataas.com/cat/60b73094e04e18001194a309/says/react" />
       </li>
    );
    // STEP 3. ๊ณ ์–‘์ด ์‚ฌ์ง„์„ ๊ทธ๋ฆด ์œ„์น˜์ธ app ์ฐพ๊ธฐ
    const ์—ฌ๊ธฐ = document.querySelector("#app");
    // STEP 4. React๋ฅผ ์‚ฌ์šฉํ•ด์„œ catItem์„ "์—ฌ๊ธฐ"์— ๊ทธ๋ฆฌ๊ธฐ (render)
    ReactDOM.render(catItem, ์—ฌ๊ธฐ);
	</script>
</body>

์ด๋ ‡๊ฒŒ๋งŒ ํ•˜๋ฉด <script /> ๋‚ด์—์„œ HTML ๋ฌธ๋ฒ•์„ ์“ด ๊ฑฐ๋ผ์„œ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜๋ฏ€๋กœ
('Uncaught SyntaxError: Unexpected token'<'' : '๊บฝ์‡  ๋ชจ์–‘์€ ๋‚ด๊ฐ€ ๋ชจ๋ฅด๋Š” token์ธ๋ฐ?'๋ผ๋Š” ์˜๋ฏธ์˜ JavaScript error๊ฐ€ ๋‚จ)
์„ธ ๊ฐ€์ง€ script ๊ด€๋ จ ๋งํฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  script์˜ type์„ "text/babel"๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.

// ๐Ÿ‘‡
// ๐ŸŽต React์˜ source code ์ถ”๊ฐ€ํ•˜๊ธฐ
<body>
  <div id="app"></div>
    // STEP 1. React library์˜ source code ์ถ”๊ฐ€
    <script
      src="https://unpkg.com/react@17/umd/react.development.js"
      crossorigin></script>
    // STEP 2. React DOM library์˜ source code ์ถ”๊ฐ€
    <script
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
      crossorigin></script>
    // STEP 3. Babel code ์ถ”๊ฐ€
    <script
	  src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    // STEP 4. <script>์˜ type ๋ณ€๊ฒฝ
    <script type="text/babel"> 
      const catItem = (
        <li>
          <img src="https://cataas.com/cat/60b73094e04e18001194a309/says/react" />
        </li>
      );

      const ์—ฌ๊ธฐ = document.querySelector("#app");
      ReactDOM.render(catItem, ์—ฌ๊ธฐ);
    </script>
</body>

JavaScript๋กœ๋งŒ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค React๋กœ ํ•˜๋Š” ๊ฒƒ์ด <script />์—์„œ๋„ HTML ๋ฌธ๋ฒ•์„ ์“ธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— code๊ฐ€ ๋” ์ง๊ด€์ ์ด๊ณ  ๊น”๋”ํ•˜๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด <script /> ๋‚ด์—์„œ JS๋กœ ์“ธ ๋•Œ๋ณด๋‹ค ์‰ฌ์šด HTML ๋ฌธ๋ฒ•์„ ์“ฐ๊ณ ๋„ HTML์— ์žˆ๋Š” <div id="app"></div>์— img๊ฐ€ ๊ทธ๋ ค์ง€๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Babel์€ ์ผ์ข…์˜ ํ†ต์—ญ์‚ฌ ('compiler'๋กœ ํ‘œํ˜„ํ•˜๊ณ  ์žˆ์Œ) ์ด๋‹ค.
๋‚ด๊ฐ€ ํŽธํ•˜๊ฒŒ ์ ์€ JSX ๋ฌธ๋ฒ•์„ browser๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ JavaScript๋กœ ๋ฐ”๊ฟ” ์ค€๋‹ค. ('Get browser-compitable JavaScript out') .
๋‚ด๊ฐ€ ์ ์€ React ๊ตฌ๋ฌธ์„ (const catItem ~ ReactDom.render ๋ถ€๋ถ„) Babel sited์—์„œ ํ™•์ธํ•ด ๋ณด๋ฉด React๋กœ ์ž‘์„ฑํ•œ code๊ฐ€ browser์˜ ์–ธ์–ด๋กœ ๋ณ€๊ฒฝ๋˜์–ด ์žˆ๋Š”๋ฐ, ์ด๋Š” ๊ฐœ๋ฐœ์ž๋„๊ตฌ์—์„œ head tag์•ˆ์— ์ƒˆ๋กœ ์ƒ๊ธด <script />์—์„œ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
e.g. React.createElement("img", ...)
Babel ๋•๋ถ„์— browser๊ฐ€ ๋‚ด code๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.


ํ•จ์ˆ˜์— component๋ฅผ ๋„ฃ๋Š” ๋ฒ•

// ๐ŸŽต {name}๊ณผ {introduction} component๋ฅผ ํ•จ์ˆ˜์— ๋„ฃ๊ธฐ
function Profile(name, introduction) {
  return (
    <div>
      <h2>{name}</h2>
      {introduction}
    </div>
  );
}

Profile("Ian", "๊ฐœ๋ฐœ ์ž˜ ํ•˜๊ณ  ์‹ถ๋‹ค."); // <div /> element์— ์žˆ๋Š” name ์ž๋ฆฌ์— "Ian", introduction ์ž๋ฆฌ์— "๊ฐœ๋ฐœ ์ž˜ ํ•˜๊ณ  ์‹ถ๋‹ค."
Profile("Mai", "๋‚˜๋„ ์–ธ์  ๊ฐ€ Typescript ํ•˜๊ณ  ์‹ถ๋‹ค."); // <div /> element์— ์žˆ๋Š” name ์ž๋ฆฌ์— "Mai", introduction ์ž๋ฆฌ์— "๋‚˜๋„ ์–ธ์  ๊ฐ€ Typescript ํ•˜๊ณ  ์‹ถ๋‹ค."

// โ†“ ์œ„์ฒ˜๋Ÿผ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋“ฏ ์“ฐ์ง€ ์•Š๊ณ  tag์ฒ˜๋Ÿผ ์“ธ ์ˆ˜๋„ ์žˆ์Œ

<Profile name ="Ian" introduction = "๊ฐœ๋ฐœ ์ž˜ ํ•˜๊ณ  ์‹ถ๋‹ค." />
<Profile name = "Mai" introduction = "๋‚˜๋„ ์–ธ์  ๊ฐ€ Typescript ํ•˜๊ณ  ์‹ถ๋‹ค." />

์ƒํƒœ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ

// ๐ŸŽต 1์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” ์ƒํƒœ ๋งŒ๋“ค๊ธฐ
const counterState = React.useState(1); // ์ธ์ž๋กœ ๋“ค์–ด๊ฐ„ 1์€ ์ดˆ๊ธฐ๊ฐ’์ž„
const counter = counterState[0]; // useState์˜ ์ฒซ ๋ฒˆ์งธ ์ƒํƒœ (counterState[0]) ๋Š” counter ๊ทธ ์ž์ฒด์ด๊ณ 
const setCounter = counterState[1]; // useState์˜ ๋‘ ๋ฒˆ์งธ ์ƒํƒœ (counterState[1]) ๋Š” counter๋ฅผ ์กฐ์ž‘ํ•œ setCounter

// โ†“ 

const [counter, setCounter] = React.useState(1);
console.log("์นด์šดํ„ฐ", counter);

2. ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์ฝ”๋“œ ์˜ˆ์‹œ

ํ•˜ํŠธ๋ฅผ ๋ˆ„๋ฅด๋ฉด ์„ธ ๋ฒˆ์งธ ์‚ฌ์ง„์ด favorites์— ์ถ”๊ฐ€๋˜๋Š” ๊ธฐ๋Šฅ

// STEP 1. favorites์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ•˜๋ฏ€๋กœ state๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ดˆ๊ธฐ๊ฐ’ ์„ค์ • const [favorite, setFavorites] = React.useState([CAT1, CAT2]);
// STEP 2. mainCard์—์„œ ํ•˜ํŠธ๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ `function handleHeartClick(){}`์ด ๋˜๋„๋ก ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด ํ•จ์ˆ˜๊ฐ€ ์ž์‹ component์— ์žˆ์œผ๋ฏ€๋กœ ๋ถ€๋ชจ component์ธ const App์œผ๋กœ ์ด๋™
// STEP 3. ๋ถ€๋ชจ component์—์„œ function handleHeartClick(){}์— `setFavorites`๋ฅผ ์„ค์ •
// STEP 4. MainCard๋Š” {handleHeartClick}์„ props๋กœ ๋ฐ›์•„์„œ ๋ฒ„ํŠผ์˜ onClick์— ์ ์šฉ

<body>
	<div id="app"></div>
    <script
      src="https://unpkg.com/react@17/umd/react.development.js"
      crossorigin></script>
    <script
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
      crossorigin></script>
    <script
	  src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <script type="text/babel">

      const MainCard = ({ img, handleHeartClick }) => {
        return (
          <div className="main-card">
            <img src={img} alt="๊ณ ์–‘์ด" width="400" />
            <button onClick={handleHeartClick}>๐Ÿค</button>
		  </div>
        );
      };

      const App = () => {
        const [favorites, setFavorites] = React.useState([CAT1, CAT2]);
        function handleHeartClick() {
          setFavorites([...favorites, CAT3]);
          // setFavorites([...favorites, CAT3]) = setFavorites([CAT1, CAT2, CAT3])
        }
        return (
          <div>
            <MainCard img={mainCat} handleHeartClick={handleHeartClick} />
            <Favorites favorites={favorites} />
          </div>
        );
      };

      const ์—ฌ๊ธฐ = document.querySelector("#app");
      ReactDOM.render(<App />, ์—ฌ๊ธฐ);

    </script>
</body>




Endnote

React ๋ฌธ์„œ - ์›น์‚ฌ์ดํŠธ์— React ์ถ”๊ฐ€
BABEL
MDN - Using Fetch
Git Hub - Public APIs
์บกํ‹ดํŒ๊ต - Asynchronous Processing, Call Back
์บกํ‹ดํŒ๊ต - Promise
์บกํ‹ดํŒ๊ต - Async์™€ Await
Inf Learn - Async์™€ Await
์บกํ‹ดํŒ๊ต - Webpack
Inf Learn - Webpack
React - ์ƒˆ๋กœ์šด React ์•ฑ ๋งŒ๋“ค๊ธฐ : Create React App
์บกํ‹ดํŒ๊ต - Node.js์™€ NPM
Inf Learn - Node.js์™€ NPM

๐Ÿ™‡ the source of this content

Inf Learn - ์ง„์œ ๋ฆผ ๋‹˜

profile
๋Š๋ ค๋„ ํ•  ๊ฑฐ์•ผ.......

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