๋ฐ˜์‘ํ˜•
250x250
Recent Posts
ยซ   2024/12   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
๊ด€๋ฆฌ ๋ฉ”๋‰ด

Hello creators ๐Ÿ™Œ

1_normal form (#์ผ๋ฐ˜ FORM ์™€ React Hook fom ๋น„๊ต) ๋ณธ๋ฌธ

[ํ”„๋ก ํŠธ์—”๋“œ(FE) ๊ฐœ๋ฐœ] (feat. ์ฃผ๋‹ˆ์–ด)/React Hook Form

1_normal form (#์ผ๋ฐ˜ FORM ์™€ React Hook fom ๋น„๊ต)

๋ถ€์‹œ๋งค๋‚˜_HA 2024. 12. 1. 23:09
728x90
๋ฐ˜์‘ํ˜•

ํ”ํžˆ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜

const DeliveryForm = () => {

const [values, setValues] = useState({
    customerName : "James", 
    mobile : "010-123-1237"
})


return (
  <form>
    <div className="form-floating mb-3">
      <input
        type="text"
        className="form-control"
        placeholder="Customer Name"
        value={values.customerName}
      />
      <label>Customer Name</label>
    </div>
  </form>
)
}
  • ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•œ ๊ฒฝ์šฐ, ์•„๋ž˜์™€ ๊ฐ™์€ ์—๋Ÿฌ ๋ฐœ์ƒ
You provided a 'value' prop to a form field without an 'onChange' handler. This will render a read-only field. If the field should be mutable use 'defaultValue'. Otherwise, set either 'onChange' or 'readOnly'

Image

์™œ, ์œ„์™€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ์™œ ๋ฐœ์ƒํ•˜๋Š” ๊ฑด๊ฐ€? (#mutable, read-only)

  1. [์‚ฌ์ „ ์ „์ œ] ๋ฆฌ์•กํŠธ๋Š” input form์ด read-only ์ƒํƒœ์ธ๊ฐ€, mutable ์ƒํƒœ์ธ๊ฐ€์— ๋”ฐ๋ผ์„œ, '๊ฐ’์„ ๋ฐ›๋Š” ๋ฐฉ์‹ ๋ฐ attribute ๊ฐ€ ๋‹ค๋ฆ„'
- ๋ฆฌ์•กํŠธ์—์„œ๋Š”, 'onChange' handler ๊ฐ€ ์—†์ด, form field ์— value ๋ฅผ ์ „๋‹ฌํ•˜๋ฉด, ๋ฆฌ์•กํŠธ๋Š” ํ•ด๋‹น form field๋ฅผ 'read-only' ๋กœ ๋‹ค๋ฃฌ๋‹ค.

- '๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ' ๋Š” 'mutable' ์ž„. 
    - mutable ์ƒํƒœ์—์„œ 
        1) ์ดˆ๊ธฐ๊ฐ’์€ defaultValue ์†์„ฑ
        2) ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด, onChange ์†์„ฑ์„ ํ†ตํ•ด์„œ ๋ณ€๊ฒฝ

- ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ์ƒํƒœ๋Š” 'immutable' ์ž„. 
    - ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, read-only ์ƒํƒœ ์ž„. 
    - ์ด๋•Œ, ๊ฐ’์„ ๋ฐ›๋Š” ๊ณณ์€ value 

react ์—์„œ form ์„ ๋‹ค๋ฃจ๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ์‹ (#useState ์˜ state ๊ฐ€ '์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜' ๊ฐ€ ๋œ๋‹ค. #์ œ์–ด ์ปดํฌ๋„ŒํŠธ)

  • ๋ฆฌ์•กํŠธ์—์„œ ํ•ด๋‹น input ํƒœ๊ทธ๊ฐ€ mutable ์ธ ๊ฒฝ์šฐ (#โญโญโญโญโญ ์ด๊ฒŒ React ์—์„œ form ์„ ๋‹ค๋ฃจ๋Š” ๋ฐฉ์‹)
    const DeliveryForm = () => {
    

const [values, setValues] = useState({
customerName : "James",
mobile : "010-123-1237"
})

const handleInputChange = (event) => {
// event ํ•ธ๋“ค๋ง ๋กœ์ง
}

return (





)
}


2. ์ด๊ฒƒ์€ React ๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ๊ฐœ๋ฐœํ•œ ๊ฑด๊ฐ€? ์•„๋‹ˆ๋ฉด input ํƒœ๊ทธ ์ž์ฒด๊ฐ€ ์ด๋ ‡๊ฒŒ ์„ค๊ณ„ ๋œ ๊ฑด๊ฐ€? (#์ œ์–ด controlled component, ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ uncontrolled component)



## ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜์— ๋Œ€ํ•ด์„œ (#์šฐํ…Œ์ฝ”) 

- '์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜' ๋ž€? 
  : 'ํ•˜๋‚˜์˜ ์ƒํƒœ' ๋Š” 'ํ•œ ๊ณณ' ์—๋งŒ ์žˆ์–ด์•ผ ํ•œ๋‹ค. 

- '์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜(single source of truth)' ์›์น™์„ ์ง€ํ‚ค๋Š”๋ฐ ์žˆ์–ด์„œ, ๊ธฐ์กด HTML ํƒœ๊ทธ๋Š” ๋ฌธ์ œ๊ฐ€ ๋œ๋‹ค? 

- '์ œ์–ด ์ปดํฌ๋„ŒํŠธ' ๋Š”, FORM ์˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’์„, REACT ๊ฐ€ ์ œ์–ด
    - ์ด๊ฑด, ์ด์ œ, '์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜(single source of truth)' ์„ฑ์งˆ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ 
    - value, onChange ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. 


## ์‹ ๋ขฐ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜์˜ ๊ด€์ ์—์„œ ์ œ์–ด ์ปดํฌ๋„ŒํŠธ 
  • name state(useState ์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž)๊ฐ€, '์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜' ๊ฐ€ ๋œ๋‹ค.
  • ์ฆ‰, value ์†์„ฑ + state ๋ฅผ ๊ฒฐํ•ฉ -> state ๋ฅผ '์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜' ๋กœ ์‚ฌ์šฉํ•จ.
    • ์ด๋•Œ, value + onChange ์กฐํ•ฉ์„ ์“ฐ๋Š” ๊ฑด react ์—์„œ read-only ๊ฐ€ ์•„๋‹ˆ๋ผ, mutable ํ•œ ์ƒํƒœ๋ฅผ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉ ๋˜๋Š” ๊ฒƒ
      ![Image](https://i.imgur.com/afxwPce.png)
      ![Image](https://i.imgur.com/81gM4wU.png)
      
      
      

์‹ ๋ขฐ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜์˜ ๊ด€์ ์—์„œ ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ

- react ๊ฐ€ form ์˜ ์ž…๋ ฅ๊ฐ’์„ ์ œ์–ดํ•˜์ง€ ์•Š๋Š”๋‹ค. 

- ๊ทธ๋Ÿผ ๋ˆ„๊ฐ€? ์–ด๋–ป๊ฒŒ? 

- 
์ด ๊ฒฝ์šฐ, value ์†์„ฑ์ด, '์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜' ๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค. 

Image

  • ์ œ์–ด vs ๋น„์ œ์–ด ๋น„๊ต
    ```
  • ์ œ์–ด ์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ,
    • ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ -> onChange ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ -> onChange ์— state ์˜ setState ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ”์ธ๋”ฉ ์™ธ์–ด ์žˆ์œผ๋ฏ€๋กœ, ๊ฐ’ ๊ฐฑ์‹  -> setState ๊ฐ€ ์‹คํ–‰๋˜์—ˆ์œผ๋ฏ€๋กœ, '๋ฆฌ๋ Œ๋”๋ง ๋ฐœ์ƒ' (#โ“โ“์™œ ๋ฆฌ์•กํŠธ๋Š” ์ด๋ ‡๊ฒŒ ์„ค๊ณ„ ํ•œ๊ฑฐ์ง€โ“โ“)
  • ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ
    • ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ ์ฃผ์ฒด๊ฐ€ DOM
    • ์‚ฌ์šฉ์ž๊ฐ€ submit ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋ฉด -> DOM ์— ์ ‘๊ทผํ•ด์„œ ๊ฐ’์„ pull ํ•ด์˜จ๋‹ค.
      • ์ด๋•Œ, ref ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ง์ ‘ DOM ์— ์ปจํƒํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒ๋˜์ง€ ์•Š์Œ.
  • ์‚ฌ์šฉ
    • '์‹ค์‹œ๊ฐ„์„ฑ' ์ด ์žˆ๋Š” ๊ฒฝ์šฐ, '์ œ์–ด ์ปดํฌ๋„ŒํŠธ' ๋กœ ํ™œ์šฉํ•˜๊ฒŒ ๋จ
    • '์ด๋ฆ„ ๋ฐ ์ฃผ์†Œ ํ•„๋“œ' ๊ฐ€ ์ฑ„์›Œ์กŒ์„ ๋•Œ, '์ œ์ถœ ๋ฒ„ํŠผ ํ™œ์„ฑํ™”' ๋ฅผ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ.
      ![Image](https://i.imgur.com/XwK2aZO.png)
      ![Image](https://i.imgur.com/AFlZ7zi.png)
      ![Image](https://i.imgur.com/62b0czN.png)
      
      
  • ๊ถ๊ธˆ์ฆ
    • setState ๊ฐ€ ์‹คํ–‰๋˜์—ˆ์œผ๋ฏ€๋กœ, '๋ฆฌ๋ Œ๋”๋ง ๋ฐœ์ƒ' (#โ“โ“์™œ ๋ฆฌ์•กํŠธ๋Š” ์ด๋ ‡๊ฒŒ ์„ค๊ณ„ ํ•œ๊ฑฐ์ง€โ“โ“)
  • ์ œ์–ด ์ปดํฌ๋„ŒํŠธ์˜ ๋‹จ์ 
    ```
  • ์‚ฌ์šฉ์ž ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ ๋งˆ๋‹ค ๋ฆฌ๋ Œ๋”๋ง
  • ๋ชจ๋“  Form Elements ์— React ์ƒํƒœ๋ฅผ ์—ฐ๊ฒฐ (#โ“โ“โ“ ์™œ)
  • non-React ์ฝ”๋“œ๋กœ ์ž‘์„ฑ๋œ Form Elements ์ฝ”๋“œ ํ†ตํ•ฉ์ด ์–ด๋ ค์›€

Image

  • React Hook Form
    ```
  • ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ
  • subscribe ๊ธฐ๋Šฅ์„ ํ†ตํ•ด, ์ฆ‰๊ฐ์ ์ธ ๋ฐ์ดํ„ฐ ์†ก์ˆ˜์‹ ์„ ๋ณด์™„

์ •๋ฆฌํ•˜๋ฉด

0. ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜๋ฅผ ๋‹ฌ์„ฑํ•˜๊ณ ์ž ํ•จ

1. React ์—์„œ form ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์—๋Š” '์ œ์–ด' ์™€ '๋น„์ œ์–ด' ๊ฐ€ ์žˆ์Œ 

2. '์ œ์–ด' ์˜ ๊ฒฝ์šฐ, 
    - mutable ์ƒํƒœ ์ด๋ฏ€๋กœ, value + onchange ์กฐํ•ฉ์„ ์ด์šฉํ•ด์„œ ๊ด€๋ฆฌ 
    - onchange ์ด๋ฒคํŠธ ์ด๊ธฐ ๋•Œ๋ฌธ์— -> ์ž…๋ ฅํ•  ๋•Œ ๋งˆ๋‹ค ๋ณ€๊ฒฝ -> ๋ฆฌ๋ Œ๋”๋ง ์œ ๋ฐœ 

3. ๋ฆฌ์•กํŠธ ํ›… ํผ์€ 
    - ๋น„์ œ์–ด ๊ธฐ๋ฐ˜
    - ์‹ค์‹œ๊ฐ„์„ฑ ๋‹จ์ ์„ subscribe ๋ฅผ ํ†ตํ•ด ๊ทน๋ณต 

์ถœ์ฒ˜

728x90
๋ฐ˜์‘ํ˜•
Comments