2024-03-03.md

๐Ÿก

DIL: ๋ชจ๋˜ ๋ฆฌ์•กํŠธ ๋”ฅ ๋‹ค์ด๋ธŒ, 0์ฃผ์ฐจ-2

์Šคํ„ฐ๋””: ์›”๊ฐ„ CS, https://github.com/monthly-cs/2024-03-modern-react-deep-dive
์˜ค๋Š˜ ์ง„ํ–‰: ๊ฐœ์ธ๊ณต๋ถ€


DIL-week0-2_2024-03-03

| DIL ์ฃผ์ฐจ | ๋ฒ”์œ„ | ๋ฐœํ‘œ ์ค€๋น„ | ๋‚ด์šฉ | ์˜ค๋Š˜์ฐจ ์ง„๋„ | | -------- | ------ | --------- | ------------------------------ | ----------- | | 0์ฃผ์ฐจ | 1, 2์žฅ | B์กฐ: 2์žฅ | ๋ฆฌ์•กํŠธ ํ•ต์‹ฌ์š”์†Œ์™€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ | 20p ~ 26p์ค‘ |

์˜ค๋Š˜ ์ฝ์€ ๋‚ด์šฉ์„ markdown์œผ๋กœ ๊ฐ„๋‹จํžˆ ๋ฉ”๋ชจ
์ฝ์€ ์‹œ๊ฐ„: 5์‹œ 50๋ถ„~9์‹œ
๋ธ”๋กœ๊ทธ ์ž‘์„ฑ: Medium blog
์˜ˆ์ œ ์ž‘์„ฑ: ./2024-03-03_sample.js

๋™๋“ฑ ๋น„๊ต: props, exhaustive deps

  • props์˜ ๋™๋“ฑ ๋น„๊ต

    • ๊ฐ์ฒด์˜ ์–•์€ ๋น„๊ต
  • react์˜ ๋ชจ๋“  ์ž‘์—…์€ ๋™๋“ฑ ๋น„๊ต๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค

    • ๊ฐ€์ƒ๋” & ์‹ค์ œ๋” ๋น„๊ต, ๋ฆฌ๋žœ๋”๋ง, ๋ฉ”๋ชจ์ด์ œ์ด์…˜ etc
  • effect hook & props & dependencies๋ž€?

    • https://react.dev/reference/react/useEffect#examples-dependencies
  • eslint-plugin-react-hooks์˜ exhaustive deps ๊ทœ์น™ ์‚ฌ์šฉ์— ๋Œ€ํ•ด์„œ

    • https://legacy.reactjs.org/docs/hooks-effect.html

      Note
      If you use this optimization, make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders. Learn more about how to deal with functions and what to do when the array changes too often.

      If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesnโ€™t depend on any values from props or state, so it never needs to re-run. This isnโ€™t handled as a special case โ€” it follows directly from how the dependencies array always works.

      If you pass an empty array ([]), the props and state inside the effect will always have their initial values. While passing [] as the second argument is closer to the familiar componentDidMount and componentWillUnmount mental model, there are usually better solutions to avoid re-running effects too often. Also, donโ€™t forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.

      We recommend using the exhaustive-deps rule as part of our eslint-plugin-react-hooks package. It warns when dependencies are specified incorrectly and suggests a fix.

      ์ฐธ๊ณ 
      ์ด ์ตœ์ ํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์ปดํฌ๋„ŒํŠธ ๋ฒ”์œ„(์˜ˆ: props ๋ฐ state)์—์„œ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋˜๋Š” ๋ชจ๋“  ๊ฐ’์„ ๋ฐฐ์—ด์— ํฌํ•จํ•ด์•ผ ํ•˜๋ฉฐ ํ•ด๋‹น ๊ฐ’๋“ค์€ ํšจ๊ณผ(effect)์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ฝ”๋“œ๊ฐ€ ์ด์ „ ๋ Œ๋”๋ง์—์„œ์˜ ์˜ค๋ž˜๋œ ๊ฐ’๋“ค์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ• ๋ฐ ๋ฐฐ์—ด์ด ๋„ˆ๋ฌด ์ž์ฃผ ๋ณ€๊ฒฝ๋  ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.
      ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰ํ•˜๊ณ  ์ •๋ฆฌ(clean up)ํ•˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋ฉด(๋งˆ์šดํŠธ์™€ ์–ธ๋งˆ์šดํŠธ ์‹œ), ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ๋นˆ ๋ฐฐ์—ด([])์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด React์—๊ฒŒ ๋‹น์‹ ์˜ ํšจ๊ณผ๊ฐ€ props๋‚˜ state๋กœ๋ถ€ํ„ฐ ์˜์กดํ•˜์ง€ ์•Š์Œ์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์‹œ ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋กœ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์œผ๋ฉฐ ํ•ญ์ƒ ์˜์กด์„ฑ ๋ฐฐ์—ด ์ž‘๋™ ๋ฐฉ์‹์œผ๋กœ ์ง์ ‘์ ์œผ๋กœ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.
      ๋นˆ ๋ฐฐ์—ด([])์„ ์ „๋‹ฌํ•˜๋ฉด ํšจ๊ณผ ๋‚ด๋ถ€์˜ props์™€ state๋Š” ํ•ญ์ƒ ์ดˆ๊ธฐ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. []๋ฅผ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์ต์ˆ™ํ•œ componentDidMount์™€ componentWillUnmount ๋ฉ”ํƒ€๋ชจ๋ธ์— ๊ฐ€๊น์ง€๋งŒ, ์ผ๋ฐ˜์ ์œผ๋กœ ๋„ˆ๋ฌด ์ž์ฃผ ํšจ๊ณผ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•œ ๋” ๋‚˜์€ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ React๋Š” useEffect๋ฅผ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฐ ํ›„๊นŒ์ง€ ์—ฐ๊ธฐํ•˜๋ฏ€๋กœ ์ถ”๊ฐ€ ์ž‘์—…์€ ๋ฌธ์ œ์ผ ๊ฐ€๋Šฅ์„ฑ์ด ์ ์–ด์ง‘๋‹ˆ๋‹ค.
      eslint-plugin-react-hooks ํŒจํ‚ค์ง€์˜ exhaustive-deps ๊ทœ์น™ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์ข…์†์„ฑ์ด ์ง€์ •๋œ ๊ฒฝ์šฐ ๊ฒฝ๊ณ ํ•˜๊ณ  ์ˆ˜์ • ์‚ฌํ•ญ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

์›์‹œํ˜• ํƒ€์ž… * 7

1. undefined

(1)์„ ์–ธํ•œ ๋ณ€์ˆ˜์— ๊ฐ’์ด ํ• ๋‹น๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜, ๊ฐ’์ด ์ฃผ์–ด์ง€์ง€ ์•Š์€ ์ธ์ˆ˜์— ์ž๋™์œผ๋กœ ํ• ๋‹น๋˜๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค

2. null

๋ช…์‹œ์ ์œผ๋กœ ๊ฐ’์ด ์—†๊ฑฐ๋‚˜, ๋น„์–ด์žˆ๋Š” ๊ฐ’์ด๋‹ค. ํŠน์ง•=>typeof๋กœ ํ™•์ธํ•˜๋ฉด object

3. Boolean: ์ฐธ๊ณผ ๊ฑฐ์ง“๋งŒ์„ ๊ฐ€์ง€๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋‹ค.

  • ํ‹ˆ์ƒˆ์ƒ์‹
    • (1)falsy๊ฐ’? false, 0, -0, 0x0n, NaN, "", null, undefined, etc...
    • (2)truthy? {}, []๋„ truthy

4. Number

  • -(2์˜ 53์Šน) -1 ~ 2์˜ 53์Šน-1 (-9,007,199,254,740,993 ~ 9,007,199,254,740,991)

MDN: Integer range for Number JSON์œผ๋กœ ์ง๋ ฌํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•  ๋•Œ, ์ด ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ์ •์ˆ˜ ๊ฐ’์€ JSON ํŒŒ์„œ๊ฐ€ ์ˆซ์ž ์œ ํ˜•์œผ๋กœ ๊ฐ•์ œ ๋ณ€ํ™˜ํ•  ๋•Œ ์†์ƒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ํ•ด๊ฒฐ์ฑ…์€ ๋Œ€์‹  ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋” ํฐ ์ˆซ์ž๋Š” BigInt ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Number's static properties

    const biggestNum = Number.MAX_VALUE;
    const smallestNum = Number.MIN_VALUE;
    const infiniteNum = Number.POSITIVE_INFINITY;
    const negInfiniteNum = Number.NEGATIVE_INFINITY;
    const notANum = Number.NaN;
    
    console.log(biggestNum); // 1.7976931348623157e+308
    console.log(smallestNum); // 5e-324
    console.log(infiniteNum); // Infinity
    console.log(negInfiniteNum); // -Infinity
    console.log(notANum); // NaN
    
  • ์˜ˆ์‹œ ์ฝ”๋“œ

    const maxInt = Math.pow(2, 53) - 1;
    
    console.log("maxInt in safe range", maxInt === Number.MAX_SAFE_INTEGER);
    
    const minInt = -(Math.pow(2, 53) - 1);
    console.log("minInt in safe range", minInt === Number.MIN_SAFE_INTEGER);
    
    // ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ number์˜ ํ•œ๊ณ„
    const outOfRangeA = biggestNum + 1;
    const outOfRangeB = biggestNum + 100;
    console.log(
      "biggestNum + 1 === biggestNum + 100",
      outOfRangeA === outOfRangeB
    );
    
  • 24p ์˜ˆ์‹œ์ฝ”๋“œ ๊ด€๋ จ ํŒŒ์ผ: ./2024-03-03_sample.js

5. Bigint

  • [ES2020], ๋์— n ๋ถ™์ด๊ฑฐ๋‚˜, Bigint() ํ•จ์ˆ˜ ์‚ฌ์šฉ

6. String

  • ๋ฌธ์ž์—ด์€ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. โŒ foo[0] = 'a'
  • console.log(Object.getOwnPropertyDescriptors(foo));
    {
      configurable: false, // ์žฌ์ •์˜ ๋ถˆ๊ฐ€๋Šฅ
      enumerable: true, // ์—ด๊ฑฐ ๊ฐ€๋Šฅ
      value: "c", // char
      writable: false // ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅ
    }[]
    
  • ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด, String and Iterator (string iterator object): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/@@iterator

7. Symbol

  • [ES6] ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ๊ณ ์œ ํ•œ ๊ฐ’, ๋ฐ˜๋“œ์‹œ Symbel() ํ•จ์ˆ˜ ์‚ฌ์šฉ
  • ๋™์ผํ•œ ์ธ์ˆ˜๋ฅผ ๋„˜๊ฒจ์ฃผ๋”๋ผ๋„ ๋™์ผํ•œ ๊ฐ’ x
  • ๋™์ผํ•œ ๊ฐ’์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” Symbol.for์„ ํ™œ์šฉ

โœ๏ธ ์˜์–ด๊ณต๋ถ€
exhaustive /iษกหˆzรดstiv/: examining, including, or considering all elements or aspects; fully comprehensive.
coerce /kลหˆษ™rs/: ๊ฐ•์ œํ•˜๋‹ค to do something by using force or threats.
type coercion coยทerยทcion /kลหˆษ™rSH(ษ™)n,kลหˆษ™rZH(ษ™)n/