Framework/React ์™„๋ฒฝ ๊ฐ€์ด๋“œ

[React ์™„๋ฒฝ ๊ฐ€์ด๋“œ] section 9 : ํ”„๋ž˜๊ทธ๋จผํŠธ ์ž‘์—…, Portals & "Refs"

yuri lee 2022. 9. 23. 08:54
๋ฐ˜์‘ํ˜•
์ด ๊ธ€์€ udemy์˜ React ์™„๋ฒฝ ๊ฐ€์ด๋“œ with Redux, Next.js, TypeScript ๊ฐ•์ขŒ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

108. ๋ชจ๋“ˆ ์†Œ๊ฐœ 

  • JSX Limitations & Fragments
  • Getting a Cleaner DOM with Portals
  • Working with Refs

109. JSX ์ œํ•œ ์‚ฌํ•ญ ๋ฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์ƒ์ˆ˜์— ์ €์žฅํ•˜๋Š” ๊ฐ’์€ ํ•˜๋‚˜์—ฌ์•ผ ํ•œ๋‹ค. 

 

1. div tag ์‚ฌ์šฉํ•˜๊ธฐ

  return (
    <div>
      {error && (
        <ErrorModal
          title={error.title}
          message={error.message}
          onConfirm={errorHandler}
        />
      )}
      <Card className={classes.input}>
        <form onSubmit={addUserHandler}>
          <label htmlFor="username">Username</label>
          <input
            id="username"
            type="text"
            value={enteredUsername}
            onChange={usernameChangeHandler}
          />
          <label htmlFor="age">Age (Years)</label>
          <input
            id="age"
            type="number"
            value={enteredAge}
            onChange={ageChangeHandler}
          />
          <Button type="submit">Add User</Button>
        </form>
      </Card>
    </div>

2. ๋„ค์ดํ‹ฐ๋ธŒ JS array ์‚ฌ์šฉํ•˜๊ธฐ 

  return [
    error && (
      <ErrorModal
        title={error.title}
        message={error.message}
        onConfirm={errorHandler}
      />
    ),
    <Card className={classes.input}>
      <form onSubmit={addUserHandler}>
        <label htmlFor="username">Username</label>
        <input
          id="username"
          type="text"
          value={enteredUsername}
          onChange={usernameChangeHandler}
        />
        <label htmlFor="age">Age (Years)</label>
        <input
          id="age"
          type="number"
          value={enteredAge}
          onChange={ageChangeHandler}
        />
        <Button type="submit">Add User</Button>
      </form>
    </Card>,
  ];

→ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๋Š” ๋ฆฌ์•กํŠธ JSX ์š”์†Œ์˜ ๋ฐฐ์—ด์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

→ ํ•˜์ง€๋งŒ ์œ„ ๋ฐฉ๋ฒ• ์‚ฌ์šฉ์‹œ ๊ฒฝ๊ณ ๊ฐ€ ๋‚˜์˜จ๋‹ค. JSX ์š”์†Œ์ธ ๋ฐฐ์—ด๋กœ ์ž‘์—…ํ•  ๋•Œ๋งˆ๋‹ค react๋Š” ๋ชจ๋“  ์š”์†Œ์— ๋Œ€ํ•œ key๋ฅผ ํ•„์š”๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

 

๋ฌธ์ œ

  • ๋ถˆํ•„์š”ํ•œ div๋“ค์ด ๋ชจ๋‘ ์‹ค์ œ DOM์œผ๋กœ ๋ Œ๋”๋ง ๋œ๋‹ค. ํŽ˜์ด์ง€์— ์–ด๋–ค ์˜๋ฏธ๋„, ๊ตฌ์กฐ์ ์ธ ์˜๋ฏธ๋„ ๊ฐ–์ง€ ์•Š์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ !
  • In bigger apps, you can easily end up with tons of unnecessary <div>s (or other elements) whick add no sematic meaning or structure to the page but are only there because of React's/JSX' requirement. 
  • ๋„ˆ๋ฌด ๋งŽ์€ html ์š”์†Œ๋ฅผ ๋žœ๋”๋งํ•˜๋ฉด ๊ถ๊ทน์ ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋Š๋ ค์งˆ ๊ฒƒ์ด๋‹ค. 

 

111. ๋ฆฌ์•กํŠธ fragment

  • It is an empty wrapper component: It doesn't render any real HTML element to the DOM. But it fulfills React's/JSX' requirement. 
return (
    <React.Fragment>
        <h2>Hi there!</h2>
    </React.Fragment>
);
return (
    <>
        <h2>Hi there!</h2>
    </>
);

 

112. ๋ฆฌ์•กํŠธ Portal ์†Œ๊ฐœ 

  • ์Šคํƒ€์ผ๋ง๋งŒ ์ œ๋Œ€๋กœ ํ•œ๋‹ค๋ฉด, modal์€ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค. ํ•˜์ง€๋งŒ "Semantically" ๊ด€์ ์ด๋‚˜ "clean HTML structure" ๊ด€์ ์œผ๋กœ ๋ณด๋ฉด ๋ณ„๋กœ ์ข‹์ง„ ์•Š๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ modal์€ ํŽ˜์ด์ง€ ์œ„์— ํ‘œ์‹œ๋˜๋Š” overlay์ด๊ธฐ ๋•Œ๋ฌธ. ์ด ๋ชจ๋‹ฌ์ด ๋‹ค๋ฅธ Html ์ฝ”๋“œ ์•ˆ์— ์ค‘์ฒฉ๋˜์–ด ์žˆ๋‹ค๋ฉด ๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” ์Šคํƒ€์ผ๋ง ๋•Œ๋ฌธ์— ์ž˜ ์ž‘๋™ํ• ์ง€๋Š” ๋ชฐ๋ผ๋„ ์ข‹์€ ์ฝ”๋“œ๋Š” ์•„๋‹ˆ๋‹ค. ์ข‹์€ ๊ตฌ์กฐ๋„ ์•„๋‹ˆ๋‹ค. 
  • ๋ฆฌ์•กํŠธ์—์„œ๋Š” Portals ์„ ์‚ฌ์šฉํ•˜๋ฉด,  overlay ๋‚ด์šฉ์ด ์žˆ๋Š” modal์ด ๊นŠ๊ฒŒ ์ค‘์ฒฉ๋˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค! 

 

113. Portal ์ž‘์—…ํ•˜๊ธฐ

  • ๋ฆฌ์•กํŠธ dom์€ ๋ธŒ๋ผ์šฐ์ €์— ๋Œ€ํ•œ ๋ฆฌ์•กํŠธ์šฉ ์–ด๋Œ‘ํ„ฐ์˜ ์ผ์ข…์ด๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค. 
  • ๋ฆฌ์•กํŠธ์— ์˜ํ•ด ์ด๋ฏธ ๋žœ๋”๋ง ๋œ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด๋ถ€๋กœ ํฌํ„ธ์‹œํ‚จ๋‹ค. ์ฆ‰ ๋ Œ๋”๋ง ํ•˜๋ ค๋Š” HTML ๋‚ด์šฉ์„ ๋‹ค๋ฅธ ์žฅ์†Œ๋กœ ์ด๋™์‹œํ‚ค๋Š” ๊ฒƒ!

 

114. "ref" ๋กœ ์ž‘์—…ํ•˜๊ธฐ 

  • ref๋Š” ์ฐธ์กฐ (reference)๋ฅผ ๋œปํ•œ๋‹ค. ๋‹ค๋ฅธ DOM ์š”์†Œ์— ์ ‘๊ทผํ•ด์„œ ์ด๋ฅผ ํ†ตํ•ด ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. ํ˜„์žฌ AddUser ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ๋งค๋ฒˆ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค state๊ฐ€ ์—…๋ฐ์ดํŠธ ๋œ๋‹ค. ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์–ป์€ ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•˜๊ณ , ๊ทธ๊ฒƒ์„ state์— ์ €์žฅํ•˜๊ณ , ๊ทธ state๋ฅผ input์— ๋‹ค์‹œ ์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด state ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ input์„ ์žฌ์„ค์ •ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ๊ณณ์œผ๋กœ ๋ณด๋‚ด๊ธฐ๋„ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ด€๋ฆฌํ•ด๋„ ์ข‹์ง€๋งŒ, form์„ ์ œ์ถœํ•  ๋•Œ๋งŒ ํ•„์š”ํ•œ๋ฐ๋„ key๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค state๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฑด ์•ฝ๊ฐ„ ๊ณผํ•˜๋‹ค. ์ด๋Ÿด ๋•Œ ref๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค! 
  • useRef๋ผ๋Š” hook์„ ์‚ฌ์šฉํ•˜์—ฌ ref๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. 
const nameInputRef = useRef();
const ageInputRef = useRef();

 
 <input
    id="username"
    type="text"
    value={enteredUsername}
    onChange={usernameChangeHandler}
    ref={nameInputRef}
  />
  
  console.log(nameInputRef);

There is a object being output here and that object has a current property. Now, that's important. This ref value, which is being generated here always is an object, whcich always has a current prop and the current prop holds the actual value that ref is connected with 

  console.log(nameInputRef.current.value);

→ value ๊ฐ’ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค! ์œ„ ๋‘๊ฐœ์˜ ref ์‚ฌ์šฉ์œผ๋กœ ์ธํ•ด usernameChageHandler, ageChangeHandler, ๊ด€๋ จ state๋ฅผ ์‚ญ์ œํ•ด๋„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค. ํ•˜์ง€๋งŒ addUser ์‹œ reset๋˜๋Š” ๋กœ์ง ์‚ฌ๋ผ์ง„๋‹ค. 

nameInputRef.current.value = "";
ageInputRef.current.value = "";

→ ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด reset๋ฅผ ์‹œ์ผœ์ฃผ๋ฉด ๋œ๋‹ค :) 

๊ทธ๋ž˜์„œ state, ref ๋ญ๊ฐ€ ๋” ์ข‹์„๊นŒ? 

  • ์˜ˆ๋ฅผ ๋“ค์–ด value๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฝ๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์žˆ๋‹ค. ๊ฐ’๋งŒ ์ฝ๊ณ  ์‹ถ๊ณ  ์•„๋ฌด๊ฒƒ๋„ ๋ฐ”๊ฟ€ ๊ณ„ํš์ด ์—†๋‹ค๋ฉด state๋Š” ํ•„์š”ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Ÿด ๊ฒฝ์šฐ์—๋Š” ref ์‚ฌ์šฉ์ด ๋” ๋‚˜์„ ๊ฒƒ. 
  • ํ•˜์ง€๋งŒ ํ˜„์žฌ ์šฐ๋ฆฌ์˜ ์ผ€์ด์Šค์—์„œ๋Š” ์›ํ•˜๋Š”๋Œ€๋กœ ์„ ํƒํ•˜๋ฉด ๋œ๋‹ค. ref๊ฐ€ ์ฝ”๋“œ๊ฐ€ ์ ๊ธด ํ•˜์ง€๋งŒ DOM์„ ์กฐ์ž‘ํ•œ๋‹ค๋Š” ์˜ˆ์™ธ์ ์ธ ์ผ์„ ํ•ด์•ผ ํ•˜๊ณ , state๋Š” ํ™•์‹คํžˆ ๋” ๊น”๋”ํ•˜์ง€๋งŒ ์ฝ”๋“œ๋ฅผ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. 

 

115. controlled ์ปดํฌ๋„ŒํŠธ์™€ uncontrolled ์ปดํฌ๋„ŒํŠธ

  • controlled component : state ์‚ฌ์šฉ 
  • uncontrolled component : ref 

https://www.udemy.com/course/best-react/

๋ฐ˜์‘ํ˜•