Material-ui: react-hook-form์œผ๋กœ ์ž‘์—…ํ•˜๊ธฐ

์— ๋งŒ๋“  2019๋…„ 11์›” 08์ผ  ยท  40์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: mui-org/material-ui

react-hook-form ๋ฐ material-ui ๋กœ ๊ฐ„๋‹จํ•œ ์–‘์‹์„ ๋งŒ๋“ค๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

  1. ์–‘์‹ ์ œ์ถœ/๊ฒ€์ฆ
  2. ์–‘์‹์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์žฌ์„ค์ •
  3. ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋กœ๋“œ

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ๋ฌธ์ œ ๊ฒ€์ƒ‰ ์ž…๋‹ˆ๋‹ค. https://github.com/mui-org/material-ui/issues/17018 ์˜ ๋ณต์ œ๋ณธ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค

  • [x] ์ด ๋ฌธ์ œ๋Š” ์ตœ์‹  ๋ฆด๋ฆฌ์Šค์— ์žˆ์Šต๋‹ˆ๋‹ค.
  • [x] ์ด ์ €์žฅ์†Œ์˜ ๋ฌธ์ œ ๋ฅผ ๊ฒ€์ƒ‰ํ–ˆ์œผ๋ฉฐ ์ด๊ฒƒ์ด ์ค‘๋ณต๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ ํ–‰๋™ ๐Ÿ˜ฏ

์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
์žฌ์„ค์ • ๊ธฐ๋Šฅ์€ ๊ฐ’์„ ์ง€์šฐ์ง€๋งŒ material-ui TextField์˜ ์ƒํƒœ๋Š” "์ฑ„์›Œ์ง„" ์ƒํƒœ๋กœ ์œ ์ง€๋˜๊ณ  ์Šคํƒ€์ผ์ด ์ง€์›Œ์ง„ ๋ฐ์ดํ„ฐ์™€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ดˆ๊ธฐ ๊ฐ’์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ๋Š” ์žฌ์„ค์ • ๊ธฐ๋Šฅ์€ ๊ฐ’์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •ํ•˜์ง€๋งŒ ๋™์ž‘์€ ์žฌ์„ค์ •๊ณผ ๋™์ผํ•˜๋ฉฐ(์ด ๊ฒฝ์šฐ ๋ฐ˜๋Œ€) ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋˜์ง€๋งŒ TextField์˜ ๋‚ด๋ถ€ ์ƒํƒœ๋Š” "์ฑ„์›Œ์ง"์ด ์•„๋‹™๋‹ˆ๋‹ค.

์˜ˆ์ƒ๋˜๋Š” ํ–‰๋™ ๐Ÿค”

material-ui ์ž…๋ ฅ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ/์‚ญ์ œ๋  ๋•Œ ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ์ƒˆ๋กœ ๊ณ ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฒˆ์‹ ๋‹จ๊ณ„ ๐Ÿ•น

์ด CodePen์—์„œ ์„ธ ๊ฐ€์ง€ ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://codesandbox.io/s/material-demo-ywutu

  1. ์ œ์ถœ: ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
  2. ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์žฌ์„ค์ •๋˜์ง€๋งŒ TextFields์˜ ์ƒํƒœ๋Š” ๋น„์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  3. ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋กœ๋“œํ•˜์ง€๋งŒ TextFields์˜ ์ƒํƒœ๊ฐ€ ์ฑ„์›Œ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

react-hook-form ํ”„๋กœ์ ํŠธ์—์„œ ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐ ํ–ˆ์ง€๋งŒ ์†Œ์œ ์ž๊ฐ€ ์—ฌ๊ธฐ์—์„œ๋„ ํ•˜๋‚˜๋ฅผ ์—ด๋ผ๊ณ  ํ•ด์„œ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค :)

enhancement external dependency

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

waiting for users upvotes ํƒœ๊ทธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๋Ÿฌํ•œ ์ง€์›์„ ์ฐพ๊ณ  ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๋ฅผ ๋‹ซ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ด ๋ฌธ์ œ์— ์ฐฌ์„ฑํ‘œ๋ฅผ ๋˜์ง€์‹ญ์‹œ์˜ค. ์ถ”์ฒœ ์ˆ˜์— ๋”ฐ๋ผ ์šฐ์„  ์ˆœ์œ„๋ฅผ ์ •ํ•ฉ๋‹ˆ๋‹ค.

https://npm-stat.com/charts.html?package=formik&package=react-hook-form&package=react-final-form

๋ชจ๋“  40 ๋Œ“๊ธ€

waiting for users upvotes ํƒœ๊ทธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๋Ÿฌํ•œ ์ง€์›์„ ์ฐพ๊ณ  ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๋ฅผ ๋‹ซ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ด ๋ฌธ์ œ์— ์ฐฌ์„ฑํ‘œ๋ฅผ ๋˜์ง€์‹ญ์‹œ์˜ค. ์ถ”์ฒœ ์ˆ˜์— ๋”ฐ๋ผ ์šฐ์„  ์ˆœ์œ„๋ฅผ ์ •ํ•ฉ๋‹ˆ๋‹ค.

https://npm-stat.com/charts.html?package=formik&package=react-hook-form&package=react-final-form

๋งŽ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค :pray::pray::pray: ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋งŽ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค!

ํ™•์‹คํžˆ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์ฑ…์ด ๋ฌด์—‡์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๊ตฌ์ฒด์ ์ธ ๋‚ด์šฉ์€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์œผ๋ฉฐ ๋‘˜ ์‚ฌ์ด์˜ ๊ธด๋ฐ€ํ•œ ํ†ตํ•ฉ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. React Hook Form๊ณผ Material UI๋Š” ๊ถํ•ฉ์ด ์ข‹์Šต๋‹ˆ๋‹ค. TypeScript์— ๋Œ€ํ•œ ์ง€์›๋„ ํ›Œ๋ฅญํ•ฉ๋‹ˆ๋‹ค.

@oliviertassinari ๋‹˜, TextField ๊ฐ€ ๊ธฐ๋ณธ ์ž…๋ ฅ์˜ API์—์„œ ๋” ์ž˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค! ์ •๋ง ๋ฉ‹์ง€๋„ค์š”. e.target.value = 'xxx' ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ํ…์ŠคํŠธ ์œ„์— ์ž๋ฆฌ ํ‘œ์‹œ์ž ํ…์ŠคํŠธ ์˜ค๋ฒ„๋ ˆ์ด๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ‘

Screen Shot 2019-11-20 at 10 06 26 am

https://codesandbox.io/s/react-hook-form-conditional-fields-delete-1frsm
์œ„์˜ ์˜ˆ์—์„œ reset API๊ฐ€ ํ˜ธ์ถœ๋œ ํ›„ <Switch /> ๊ฐ€ ์žฌ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์–‘์‹ ์ž…๋ ฅ API(์ž…๋ ฅ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด ๊ฐ’ ์„ค์ • ๋ฐ ์žฌ์„ค์ •)๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ์–‘์‹ ๊ด€๋ จ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ •๋ง ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ํฐ ์ž‘์—…์ด๊ณ  react-hook-form๊ณผ ๊ฐ™์€ ์ž‘์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ง€์›ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ๊ณ ๋ คํ•ด์•ผ ํ•  ์‚ฌํ•ญ (์•„๋งˆ๋„ lib๊ฐ€ ๋” ์œ ๋ช…ํ•ด์งˆ ๋•Œ๊นŒ์ง€ โค๏ธ)

๋‹ค์‹œ ํ•œ ๋ฒˆ ์ด ๋ฌธ์ œ๋ฅผ ์กฐ์‚ฌํ•˜๊ธฐ ์œ„ํ•œ ๊ท€ํ•˜์˜ ์‹œ๊ฐ„๊ณผ ๋…ธ๋ ฅ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋˜ํ•œ MUI์™€ ํ•จ๊ป˜ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์ด ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

๊ฑด๋ฐฐ
์ฒญ๊ตฌ์„œ

@bluebill1049 ๋ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ข‹์€ ๊ฒฌ์ธ๋ ฅ์„ ์–ป๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์—ฌ์ „ํžˆ formik์— ํ•œ์ฐธ ๋’ค๋–จ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šค์œ„์น˜ ์žฌ์„ค์ •์ด ์œ ์ผํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๊นŒ?

๋‹ค์‹œ ์—ด์–ด ์ด ๋ฌธ์ œ๋ฅผ react-hook-form ๋Š” ์•„์ง ์ด ๋งˆ์„์˜ ์‹ ์ธ์ด๊ณ  ๋” ๋งŽ์€ ์‚ฌ์šฉ์ž๊ฐ€ react-hook-form ์ฑ„ํƒํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋” ๋งŽ์€ ์‹œ๊ฐ„์„ ๊ฐ–๊ณ  ์‹ถ๋‹ค๋ฉด ํ–‰๋™์ด ์—†์Šต๋‹ˆ๋‹ค. ์™„์ „ ํ•ฉ๋ฆฌ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๋™์•ˆ react-hook-form ์™€ ํ˜ธํ™˜๋˜๋Š” ์ž…๋ ฅ ํ…Œ์ด๋ธ”์„ ์ƒ์ž ๋ฐ–์œผ๋กœ ์ƒ์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค(์ฝ”๋“œ์ƒŒ๋“œ๋ฐ•์Šค์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ผ ์ˆ˜ ์žˆ์Œ). ์—ฌ๊ธฐ์—๋„ ๊ฒŒ์‹œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

react-hook-form์ด ์ž˜ ์ž‘๋™ํ•˜๊ณ  ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•˜๋ฉด ๊ธฐ๋ณธ ์ž…๋ ฅ API(๋’ค์—์„œ ๋ฐ˜์‘ ํ›„ํฌ ์–‘์‹์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ)๋กœ ์ž‘์—…ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. input ์„ ์–ป๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. select , radio ๋ฐ checkbox ๋Š” ์–‘์‹์˜ ๊ธฐ๋ณธ ์šฉ๋„์ž…๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ @oliviertassinari ์ €๋Š” MUI์™€ react-hook-form ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ์„ ์ขํž ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/react-hook-form/react-hook-form-input

๋˜ํ•œ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ์žฌ์„ค์ •ํ•˜๊ณ  ๋กœ๋“œํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค. ๋˜๋Š” ์ ์–ด๋„ ์ง€๊ธˆ์€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค.

์•ˆ๋…•ํ•˜์„ธ์š” @raikusy ์ œ๊ฐ€ ์œ„์— ๊ฒŒ์‹œํ•œ ๋งํฌ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์žฅ๊ธฐ์ ์œผ๋กœ MUI ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๊ธฐ๋ณธ ํ˜•์‹ api '์žฌ์„ค์ •'์„ ์ง€์›ํ•˜๊ณ  ๊ตฌ์„ฑ ์š”์†Œ 'ref'๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์ง€๋งŒ ์ด๊ฒƒ์€ MUI์— ๋งŽ์€ ๊ธฐ๋Šฅ๊ณผ ์•„์ด๋””์–ด๊ฐ€ ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•˜๋Š” ํฐ ์ž‘์—… ๋น„์šฉ์ž…๋‹ˆ๋‹ค. ์–ด๋Š ๊ฒƒ์ด ๋” ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜์‘ ํ›„ํฌ ํ˜•์‹์ด ์ฃผ๋ฅ˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋˜๊ฑฐ๋‚˜ ๋Œ€์ค‘ํ™”๋  ๋•Œ๊นŒ์ง€ ์œ„์—์„œ ๋…ผ์˜ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ MUI๋Š” ์†”๋ฃจ์…˜ ์กฐ์‚ฌ๋ฅผ ์‹œ์ž‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์˜๋ฏธ๊ฐ€ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค :) ๋ฐ˜์‘ ํ›„ํฌ ์–‘์‹๋„ ์‚ฌ์šฉํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค โค๏ธ๐Ÿคฉ๐ŸคŸ๐Ÿป

์ฐธ๊ณ ๋กœ ๋ž˜ํผ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์—ฌ์ „ํžˆ ur ์–‘์‹์ด 0์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋Š” ๋ž˜ํผ ๊ตฌ์„ฑ ์š”์†Œ ๋‚ด์—์„œ ๊ฒฉ๋ฆฌ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.๐Ÿคฉ๐ŸคŸ๐Ÿป๐Ÿ’ƒ

@bluebill1049 ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋ณด๊ธฐ ์ข‹์Šต๋‹ˆ๋‹ค. props์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ์–‘์‹ ํ•„๋“œ๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์„ ๊ฐ–๋Š” ์กฐ๊ฑด์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด TextField ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์œ„์˜ ์†”๋ฃจ์…˜์—์„œ๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? ๋˜ํ•œ ์–‘์‹์— ์†Œํ’ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ๊ฐ’์„ ์ „๋‹ฌํ•˜๋Š” ๋” ๋‚˜์€ ์˜ˆ๋ฅผ ์ฐพ๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. props๋Š” ํผ์ด ์ด๋ฏธ ๋งˆ์šดํŠธ๋œ ํ›„ api ํ˜ธ์ถœ์—์„œ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@raikusy ๋ž˜ํผ ๊ตฌ์„ฑ ์š”์†Œ์™€ ํ•จ๊ป˜ reset/setValue API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์žฌ์„ค์ •: ์ „์ฒด ์–‘์‹ -> https://react-hook-form.com/api#setValue
setValue: ๊ฐœ์ธ์šฉ - > https://react-hook-form.com/api#reset

RHF๋กœ ์ž‘์—…ํ•˜๊ธฐ ์œ„ํ•ด <Slider /> ์„(๋ฅผ) ์–ป์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉ:

      <FormControl fullWidth component="fieldset" margin="normal">
        <FormLabel component="legend">Palavras</FormLabel>
        <RHFInput
          as={<Slider min={100} max={1200} step={100} valueLabelDisplay="auto" marks={marks} />}
          type="input"
          name="words"
          register={register}
          setValue={setValue}
        />
      </FormControl>

๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Warning: Failed prop type: Invalid prop `value` supplied to `ForwardRef(Slider)`.
    in ForwardRef(Slider) (created by WithStyles(ForwardRef(Slider)))
    in WithStyles(ForwardRef(Slider)) (created by SetupAccountForm)
    in Unknown (created by SetupAccountForm)
    in fieldset (created by ForwardRef(FormControl))
    in ForwardRef(FormControl) (created by WithStyles(ForwardRef(FormControl)))
    in WithStyles(ForwardRef(FormControl)) (created by SetupAccountForm)
    in form (created by SetupAccountForm)
    in SetupAccountForm (created by SetupAccountPage)
    in div (created by ForwardRef(CardContent))
    in ForwardRef(CardContent) (created by WithStyles(ForwardRef(CardContent)))
    in WithStyles(ForwardRef(CardContent)) (created by SetupAccountPage)
    in div (created by ForwardRef(Paper))
    in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
    in WithStyles(ForwardRef(Paper)) (created by ForwardRef(Card))
    in ForwardRef(Card) (created by WithStyles(ForwardRef(Card)))
    in WithStyles(ForwardRef(Card)) (created by SetupAccountPage)
    in div (created by ForwardRef(Grid))
    in ForwardRef(Grid) (created by WithStyles(ForwardRef(Grid)))
    in WithStyles(ForwardRef(Grid)) (created by Layout)
    in Layout (created by SetupAccountPage)
    in SetupAccountPage (created by App)
    in Route (created by App)
    in Switch (created by App)
    in Router (created by HashRouter)
    in HashRouter (created by App)
    in App (created by Root)
    in div (created by ForwardRef(Container))
    in ForwardRef(Container) (created by WithStyles(ForwardRef(Container)))
    in WithStyles(ForwardRef(Container)) (created by Root)
    in div (created by Styled(MuiBox))
    in Styled(MuiBox) (created by Root)
    in Provider (created by Root)
    in Root Button.js:233:15

@hbarcelos ์Šฌ๋ผ์ด๋” ๊ฐ™์€ ์™ธ๋ชจ ๊ฐ’ ์†Œํ’ˆ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค :( ๋‚˜๋Š” ๊ฑฐ๊ธฐ์— ๋ช‡ ๊ฐ€์ง€ ์กฐ์‚ฌ๋ฅผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ ๋™์•ˆ, ๋‹น์‹ ์€์— ๋“ฑ๋ก๋˜๋Š” ๋“ฑ๋ก ์‚ฌ์šฉ์ž ์ •์˜ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค useEffect

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @bluebill1049

๋‚˜๋Š” ๊ฒฐ๊ตญ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

import React, { useEffect, useCallback, useState, useMemo } from 'react';
import t from 'prop-types';
import clsx from 'clsx';
import { makeStyles } from '@material-ui/core/styles';
import Box from '@material-ui/core/Box';
import Slider from '@material-ui/core/Slider';

const useStyles = makeStyles(theme => ({
  sliderWrapper: {},
  sliderLabel: {
    marginTop: theme.spacing(1),
    marginBottom: theme.spacing(0.5),
    color: theme.palette.primary.main,
  },
}));

function CustomSlider({
  register,
  unregister,
  setValue,
  name,
  rules,
  defaultValue,
  valueLabelAs,
  formatLabel,
  ...rest
}) {
  const cl = useStyles();

  const [currentValue, setCurrentValue] = useState(defaultValue);

  useEffect(() => {
    register({ name });
    return () => unregister(name);
  }, [defaultValue, name, register, setValue, unregister]);

  const valueLabel = useMemo(() => {
    if (!valueLabelAs) {
      return null;
    }

    return React.cloneElement(
      valueLabelAs,
      { className: clsx(valueLabelAs.props.className, cl.sliderLabel) },
      formatLabel(currentValue)
    );
  }, [cl.sliderLabel, currentValue, formatLabel, valueLabelAs]);

  const handleChange = useCallback(
    (_, value) => {
      setValue(name, value);
      setCurrentValue(value);
    },
    [name, setValue]
  );

  return (
    <React.Fragment>
      {valueLabel}
      <Box className={cl.sliderWrapper}>
        <Slider {...rest} onChange={handleChange} defaultValue={defaultValue} />
      </Box>
    </React.Fragment>
  );
}

CustomSlider.defaultProps = {
  rules: {},
  defaultValue: '',
  valueLabelAs: null,
  formatLabel: v => v,
};

CustomSlider.propTypes = {
  register: t.func.isRequired,
  unregister: t.func.isRequired,
  setValue: t.func.isRequired,
  name: t.string.isRequired,
  rules: t.object,
  defaultValue: t.oneOfType([t.number, t.string]),
  valueLabelAs: t.node,
  formatLabel: t.func,
};

export default CustomSlider;

์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ๋„ ๋งŽ์ด ํ•„์š”ํ–ˆ๋‹ค

์žฅ๊ธฐ์ ์œผ๋กœ MUI ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๊ธฐ๋ณธ ์–‘์‹ API '์žฌ์„ค์ •'์„ ์ง€์›ํ•˜๊ณ  ๊ตฌ์„ฑ ์š”์†Œ 'ref'๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@bluebill1049 ์ด๊ฑด React๋‚˜ react-hook-form ์ž์ฒด์˜ ๋ฌธ์ œ ์•„๋‹Œ๊ฐ€์š”? ๊ฐœ๋ฐœ์ž๋Š” react-hook-form์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ์ƒํƒœ ๋ณ€๊ฒฝ์— "๋ฐ˜์‘"ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?
๋‚ด๊ฐ€ ์‚ฌ์šฉ์ž ์ •์˜ ์ž…๋ ฅ์„ ๊ตฌ์ถ•ํ•˜๋Š” React ๊ฐœ๋ฐœ์ž์ด๊ณ  ์š”์†Œ๊ฐ€ ์ฑ„์›Œ์ง€๊ฑฐ๋‚˜ ๋น„์–ด ์žˆ์„ ๋•Œ ๋‹ค๋ฅด๊ฒŒ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ React์˜ ์„ ์–ธ์  ๋ชจ๋ธ "์™ธ๋ถ€์—์„œ" ์ž…๋ ฅ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ? @test-library/react ์—์„œ ์ˆ˜ํ–‰ ๋˜๋Š”

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธฐ๋ณธ ์ž…๋ ฅ ์š”์†Œ์— ์˜์กดํ•˜๋Š” Material-UI ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ Slider์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž ์ •์˜ ๋ž˜ํผ๊ฐ€ ์—ฌ์ „ํžˆ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์Šฌ๋ผ์ด๋”์—๋Š” ๊ฐ’ ์†Œํ’ˆ์ด ์žˆ์ง€๋งŒ onChange์˜ ์„œ๋ช…์€ ๊ธฐ๋ณธ ์ž…๋ ฅ๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์–‘์‹ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ #15585์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ†ตํ•ฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.


์ด ๋ฌธ์ œ๊ฐ€ ์™œ ๊ทธ๋ ‡๊ฒŒ ๋งŽ์€ ์ฐฌ์„ฑ์„ ์–ป์—ˆ๋Š”์ง€ ๊ถ๊ธˆํ–ˆ๋Š”๋ฐ, ์•Œ๊ฒŒ ๋œ ๊ฒƒ ๊ฐ™์•„์š” ๐Ÿ™ƒ:

Capture dโ€™eฬcran 2019-12-07 aฬ€ 20 41 31
https://react-hook-form.com/advanced-usage#ControlledmixedwithUncontrolledComponents

@oliviertassinari , ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ž์„ธํžˆ ์‚ดํŽด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ‘

๋‚ด๊ฐ€ ์‚ฌ์šฉ์ž ์ •์˜ ์ž…๋ ฅ์„ ๊ตฌ์ถ•ํ•˜๋Š” React ๊ฐœ๋ฐœ์ž์ด๊ณ  ์š”์†Œ๊ฐ€ ์ฑ„์›Œ์ง€๊ฑฐ๋‚˜ ๋น„์–ด ์žˆ์„ ๋•Œ ๋‹ค๋ฅด๊ฒŒ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์ž…๋ ฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋‚ด ํ”„๋กœ์ ํŠธ์˜ ์†”๋ฃจ์…˜์— ๋Œ€ํ•œ CSS ์„ ํƒ๊ธฐ๋ฅผ ์ฐพ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ: ์š”์†Œ ์„ ํƒ์— ๋นˆ ๊ฐ’์ด ์žˆ๊ณ  ์Šคํƒ€์ผ ํ‘œ์‹œ. ๋Œ€์•ˆ์œผ๋กœ react-hook-form watch API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋นˆ ๊ฐ’์„ ๊ฐ์ง€ํ•˜๊ณ  prop (๋‚ด ๋ž˜ํ•‘๋œ ์ž…๋ ฅ ๊ตฌ์„ฑ ์š”์†Œ ํฌํ•จ)๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ React์˜ ์„ ์–ธ์  ๋ชจ๋ธ "์™ธ๋ถ€์—์„œ" ์ž…๋ ฅ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ? @test-library/react์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ?

์˜ˆ, ์šฐ๋ฆฌ๋Š” react-hook-form-input ์•„๋ž˜์—์„œ ๊ฝค ๋งŽ์ด ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜„

์ €๋Š” ์ˆ˜๋…„ ๋™์•ˆ ์–‘์‹์„ ์ œ์–ดํ•œ ํ›„์— ์–‘์‹์„ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ œ์–ด๋˜์ง€ ์•Š๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ฏฟ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š” ํ›จ์”ฌ ๋” ์‰ฝ๊ฒŒ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (Facebook LOL์—์„œ ์ผํ•˜๋Š” ๊ฒฝ์šฐ) ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ ์–‘์‹์„ ์ž‘์„ฑํ•  ๋•Œ ๋‚ด ์ง์žฅ ์ƒํ™œ๊ณผ ์ฃผ๋ณ€ ์‚ฌ๋žŒ๋“ค์„ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. HTML ์ž…๋ ฅ์€ ์ž์ฒด์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ด๋ฅผ ์ˆ˜์šฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค(์˜ณ๊ณ  ๊ทธ๋ฆ„์„ ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋Œ€์ฒด ์†”๋ฃจ์…˜).

์ €๋Š” React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์„ ๋งค์šฐ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ฃผ๋ณ€์— ๋งŽ์€ ํŒจํ‚ค์ง€๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” React๊ฐ€ ์ œ์–ด๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ˆ˜์šฉํ•˜๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ react-hook-form ์€ register ์—์„œ useEffect register ์‚ฌ์šฉ์ž ์ •์˜๋ฅผ ๊ณ„์† ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๊ฐ€ ์ œ์–ด๋˜๋Š” ์–‘์‹์„ ๋นŒ๋“œํ•˜๋Š” ๊ฒƒ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก :

์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด ๋ฌธ์ œ์™€ ๊ด€๋ จ๋œ ๋‚ด ์›น์‚ฌ์ดํŠธ์˜ ๋งํฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ react-hook-form-input ๋ฅผ ํฌํ•จํ•˜๋„๋ก ์ด ํŽ˜์ด์ง€๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

https://material-ui.com/components/text-fields/#complementary -projects

์˜ˆ, ์šฐ๋ฆฌ๋Š” react-hook-form-input์—์„œ ๊ฑฐ์˜ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@bluebill1049 ๋‚ด ์ œ์•ˆ๊ณผ ๋ฐ˜๋Œ€๋˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ๋‹ค์Œ ์‚ฌํ•ญ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ˜์‘ ํ›„ํฌ ํ˜•์‹:

    1. ์ž…๋ ฅ DOM ๋…ธ๋“œ๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ๋•Œ input.value = 'x' ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ž…๋ ฅ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— React์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค .

    2. react-hook-form์€ ์ž…๋ ฅ ๊ฐ’ ๋ณ€๊ฒฝ์„ ์ˆ˜์‹  ๋Œ€๊ธฐํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ž…๋ ฅ์— "์ž…๋ ฅ" ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค . ์ด๋Š” ์ œ์–ด๋œ ์ž…๋ ฅ์—์„œ ๊ฐ’์ด ๋ณ€๊ฒฝ ๋  ๋•Œ React์— ์˜ํ•œ ๋ณ€๊ฒฝ์ด ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

  • react-hook-form-input: ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋Š” react-hook-form(i ๋ฐ ii)์˜ ์ด์ „ ๋‘ ๊ฐ€์ง€ ์ œํ•œ ์‚ฌํ•ญ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ž…๋ ฅ์„

1. React๊ฐ€ react-hook-form ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ํ›Œ๋ฅญํ•˜๊ฒŒ ์ž‘๋™ํ•  ๊ฐ€๋Šฅ์„ฑ์€ ๋งค์šฐ ๋‚ฎ๊ณ  2. react-hook-form์ด ์ œ์–ด ๋ฐ ์˜์‚ฌ ์ œ์–ด๋˜์ง€ ์•Š์€ ์ž…๋ ฅ( ๊ธฐ๋ณธ๊ฐ’๊ณผ onChange๋งŒ ์ˆ˜์‹ ํ•˜๋Š” ๊ฐ’), ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

  1. react-hook-form์€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ œ์–ด ๋ฐ ์˜์‚ฌ ์ œ์–ด๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋ฅผ ํŒจ์น˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ i ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค ii. (๋งํฌ๋œ ์ฝ”๋“œ โ€‹โ€‹๋ฐ ์ƒ์ž์—์„œ ์ œ์•ˆ๋œ ์†”๋ฃจ์…˜ ์ฐธ์กฐ: dispatch + defineProperty).
  2. Material-UI๋Š” ํ•„์š”ํ•  ๋•Œ react-hook-form์— ๋Œ€ํ•œ ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ๋„์›€์„ ๊ตฌํ•ฉ๋‹ˆ๋‹ค(#15585 ๊ด€๋ จ).
  3. ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค ๐Ÿ‘Œ

@oliviertassinari ์ž์„ธํ•œ ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ œ์•ˆ๋œ ์†”๋ฃจ์…˜์œผ๋กœ ์ถ”๊ฐ€ ์กฐ์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. :)

์œ„์—์„œ ์–ธ๊ธ‰ํ•œ React ๋ฌธ์ œ์˜ ๋Œ€๋ถ€๋ถ„์€ ๋‚ด๊ฐ€ ๊ฐœ์„ ํ•˜๊ณ  ์‹ถ์€ ๋ถ€๋ถ„์ธ ์ œ์–ด๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ „ํ™˜ํ•  ๋•Œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ช…ํ™•ํžˆํ•˜๊ธฐ ์œ„ํ•ด :

  • ๋ณ€๊ฒฝ ์‹œ ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๋ ค๋ฉด https://codesandbox.io/s/heuristic-galileo-1wf8c๋กœ ์ด๋™ํ•˜์—ฌ ๋ฒ„ํŠผ => ๋ˆ„๋ฝ๋œ ๋กœ๊ทธ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ https://codesandbox.io/s/silly-allen-72zz7 ๋กœ
  • ๊ฐ’ ๋ณ€๊ฒฝ ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๋ ค๋ฉด https://codesandbox.io/s/elastic-agnesi-osuuy๋กœ ์ด๋™ํ•˜์—ฌ ๋ฒ„ํŠผ => ๋ˆ„๋ฝ๋œ ๋กœ๊ทธ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ https://codesandbox.io/s/sparkling-rain-3rebh ๋กœ

๋”ฐ๋ผ์„œ ๋ฐ˜์‘ ํ›„ํฌ ํ˜•์‹์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์„ ์‹œ๋„/๋ฐฐํฌํ•˜๊ณ  ๋ฌธ์„œ์—์„œ ์šฐ๋ฆฌ ์ธก์˜ ์ฑ…์ž„์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์–‘์‹ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋งค๋ ฅ์„ ๋†’์ด๋Š” ๋ฐ ์ •๋ง ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. D.

์œ„์—์„œ ์–ธ๊ธ‰ํ•œ React ๋ฌธ์ œ์˜ ๋Œ€๋ถ€๋ถ„์€ ์ œ์–ด๋˜์ง€ ์•Š๋Š” ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๊ฐœ์„ ํ•˜๊ณ  ์‹ถ์€ ๋ถ€๋ถ„์ธ ์ œ์–ด ๋˜๋Š” ์ œ์–ด๋˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์ „ํ™˜ํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

React๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ œ์–ด๋˜์ง€ ์•Š์Œ๊ณผ ์ œ์–ด๋จ ์‚ฌ์ด๋ฅผ ์ „ํ™˜ํ•  ๋•Œ ๊ฒฝ๊ณ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์˜ ์š”์ ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฐ˜์‘ ํ›„ํฌ ํ˜•์‹์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์„ ์‹œ๋„/๋ฐฐํฌํ•˜๊ณ  ๋ฌธ์„œ์—์„œ ์šฐ๋ฆฌ ์ธก์˜ ์ฑ…์ž„์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” MUI๋ฅผ ๋น„๋‚œํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์•„์‹œ๋‹ค์‹œํ”ผ, react-hook-form์€ ์ด ๋งˆ์„์˜ ์ƒˆ๋กœ์šด ์†Œ๋…„์ž…๋‹ˆ๋‹ค. ์ €๋Š” ํŠน์ • ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ด€์‹ฌ์ด๋‚˜ ์ถ”์ง„๋ ฅ์„ ์–ป์œผ๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋ณด์ด์…จ๋‹ค๋ฉด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค(๋น„๋‚œ). ๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ท€ํ•˜์˜ ๋„์›€๊ณผ ์กฐ์‚ฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

image
(๋น„๋‚œ์ด ์•„๋‹˜)

์œ„์—์„œ ์–ธ๊ธ‰ํ•œ React ๋ฌธ์ œ์˜ ๋Œ€๋ถ€๋ถ„์€ ์ œ์–ด๋˜์ง€ ์•Š๋Š” ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๊ฐœ์„ ํ•˜๊ณ  ์‹ถ์€ ๋ถ€๋ถ„์ธ ์ œ์–ด ๋˜๋Š” ์ œ์–ด๋˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์ „ํ™˜ํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

React๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ œ์–ด๋˜์ง€ ์•Š์Œ๊ณผ ์ œ์–ด๋จ ์‚ฌ์ด๋ฅผ ์ „ํ™˜ํ•  ๋•Œ ๊ฒฝ๊ณ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์˜ ์š”์ ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค ์ œ์–ด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค :) ๋‚ด ์˜๊ฒฌ์„ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

@bluebill1049 ๊ต‰์žฅ

๊ณ ๋งˆ์›Œ, @oliviertassinari (๋‹น์‹ ์€ ๋งค์šฐ ์นœ์ ˆํ•ฉ๋‹ˆ๋‹ค)

Material-UI๋Š” ์ œ์•ˆ๋œ ๋™์ผํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. 1. Material-UI์—์„œ๋งŒ ์ž‘๋™ํ•˜๋ฉฐ ๋™์ผํ•œ ๋…ธ๋ ฅ์„ ๊ณ„์†ํ•ด์„œ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 2. ์ด๋Ÿฌํ•œ "ํ•ดํ‚น"์˜ ์†Œ์œ ๊ถŒ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ทจํ•œ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„(๊ด€์šฉ์ ์ธ React API ์šฐํšŒ)์—์„œ ๋น„๋กฏ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ฐ˜์‘ ํ›„ํฌ ํ˜•์‹์œผ๋กœ ์œ ์ง€๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„, ๋ˆ„๊ตฐ๊ฐ€ ์ด ๋ฌธ์ œ์— ๊ฐœ์ž…ํ•  ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ. (์ž ์‹œ ๋™์•ˆ ๋น„๋ฐ€๋ฆฌ์— ์ž‘์—…ํ–ˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜“)

์šฐ๋ฆฌ๋Š” ํŠนํžˆ ์ œ์–ด๋˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์ผ๋ถ€ ์‚ถ์˜ ์งˆ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ๋Š” RHF์˜ ๋‹ค์Œ ์ฃผ์š” ๋ฒ„์ „์„ ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ง€์›์ด ๊ฐœ์„ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋Š” ์ œ์–ด๋œ UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด setValue ๋ฐ defaultValue ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋™์‹œ์— ์•ฑ/์–‘์‹ ์ˆ˜์ค€์—์„œ ์ตœ์†Œ ๋‹ค์‹œ ๋ Œ๋”๋ง์„ ์œ ์ง€ํ•˜๊ณ  ์ž…๋ ฅ ๊ตฌ์„ฑ ์š”์†Œ ์ˆ˜์ค€์—์„œ ๋‹ค์‹œ ๋ Œ๋”๋ง์ด ๊ฒฉ๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ RHF์˜ V4๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์˜ ๊ตฌ๋ฌธ์ž…๋‹ˆ๋‹ค.

import TextField from '@material-ui/core/TextField';

const { control } = useForm();

<Controller as={TextField} control={control} name="firstName" rules={{ required: true }} />

๋„์›€์ด ํ•„์š”ํ•˜๋‹ค.
์žฌ๋ฃŒ์˜ ํ…์ŠคํŠธ ํ•„๋“œ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(์•„๋งˆ๋„ ๋‹ค๋ฅธ mui๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž„).
ํ…์ŠคํŠธ ํ•„๋“œ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด ์ฒซ ๋ฒˆ์งธ ํ‚ค ์ €์žฅ์†Œ๊ฐ€ ๋Š๋ฆฌ๊ณ  ๊ฐ’์„ ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋ณ€๊ฒฝํ•  ๋•Œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.
์–ด๋–ค ์ด์œ ๋กœ ์ „์ฒด ์–‘์‹์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

Screen Shot 2020-02-11 at 3 21 25 AM

ezgif com-video-to-gif

๋น ๋ฅธ ์ฐธ๊ณ  ์‚ฌํ•ญ : ์ง€์ฒด ์—†์ด ๋น ๋ฅด๊ฒŒ ์ž…๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€์—ฐ ๋ถ€๋ถ„์€ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ์ด์œ  ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„, ์ด ๋ฌธ์ œ๋Š” react-hook-form์—์„œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๊ณ„์† ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
์ด ๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋‚ด๊ฐ€ ์ž˜๋ชปํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ: https://codesandbox.io/s/example-muitextfield-setvalue-with-react-hook-form-kqwq0?file=/index.js

ํŽธ์ง‘: ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์†”๋ฃจ์…˜์€ InputLabelProps={isEdition && { shrink: isEdition }}
์—ฌ๊ธฐ์„œ isEdition ๋Š” ํŽธ์ง‘ ํ™”๋ฉด์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ”Œ๋ž˜๊ทธ์ž…๋‹ˆ๋‹ค.

@Luccasoli plz๋Š” ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค: https://react-hook-form.com/api#Controller

MUI ์˜ˆ์ œ๊ฐ€ ์žˆ๋Š” ์˜ˆ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. https://codesandbox.io/s/react-hook-form-controller-079xx

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค @bluebill1049 , ํ•˜์ง€๋งŒ ์ด ์˜ˆ์ œ์—์„œ ๋น„์Šทํ•œ ์ƒํ™ฉ์„ ์ฐพ์ง€ ๋ชปํ–ˆ๊ณ  ๋ฌธ์„œ์—์„œ ์ด ๋ฌธ์ œ๋ฅผ ์ œ๋Œ€๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์†Œํ’ˆ์„ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.(

Screen Shot 2020-04-15 at 9 21 56 am

@Luccasoli defaultValue ๋ณด์„ธ์š”.

๋‚˜๋Š” ์‹œ๋„ํ–ˆ๋‹ค:

  • useForm() ๋‚ด๋ถ€์˜ defaultValues๋ฅผ ์ƒํƒœ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๊ณ  useEffect() ๋‚ด๋ถ€์—์„œ ํ•ด๋‹น ์ƒํƒœ๋ฅผ ์„ค์ •ํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋‚˜๋Š” ๊ฐ™์€ ์•„์ด๋””์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์ง€๋งŒ defaultValue ์†Œํ’ˆ์—์„œ ์ง์ ‘ ๊ฐ ์ปจํŠธ๋กค๋Ÿฌ

๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ• ๋ชจ๋‘, textField๋Š” ์ž…๋ ฅ์ด ์ฑ„์›Œ์ง„ ๊ฒƒ์„ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋ ˆ์ด๋ธ”์ด ์ž…๋ ฅ ์œ„์— ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

์˜ˆ, ํ•˜์ง€๋งŒ ์ด์ƒํ•˜๊ฒŒ๋„ defaultValue๋ฅผ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ์ด์ƒํ•œ ๊ฐ’์„ ํ‘œ์‹œํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ํ•ญ์ƒ ๋นˆ ๋ฌธ์ž์—ด ๊ฐ’์œผ๋กœ ์‹œ์ž‘ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

"Loading" defaultValue๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๋นˆ ์ดˆ๊ธฐ ๊ฐ’์ด ์—ฌ์ „ํžˆ ๋” ํฅ๋ฏธ๋กญ๊ฒŒ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

ํŽธ์ง‘: ์˜ˆ, ๋นˆ ๋ฌธ์ž์—ด์—์„œ๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค... ํ•˜ํ•˜ํ•˜, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ „์— ์‹œ๋„ํ•œ ์ ์ด ์žˆ๋‹ค๊ณ  ๋งน์„ธํ–ˆ์ง€๋งŒ ๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@bluebill1049 ๋‚ด๊ฐ€ ๋ณด๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๋ฐ๋ชจ๋ฅผ ์กฐ์ •ํ–ˆ์œผ๋ฉฐ ์ข‹์€ ์†”๋ฃจ์…˜์ด ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.
https://codesandbox.io/s/react-hook-form-controller-n196b?file=/src/index.js
๋ฒ„ํŠผ์„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์ „์— ํ™•์ธ๋ž€์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋Š” ๊ฒƒ์ด ์„ ํƒ๋ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•œ ๋‹ค๋ฅธ ๋ชจ๋“  ํ•„๋“œ๋Š” ํ™•์ธ๋ž€์„ ์ œ์™ธํ•˜๊ณ  ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด ์ƒŒ๋“œ ๋ฐ•์Šค๊ฐ€ Material UI์— ์ •๋ง ์œ ์šฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ์Šฌ๋ผ์ด๋”, Select ๋ฐ ๊ธฐํƒ€ ๋ช‡ ๊ฐ€์ง€์— ๋Œ€ํ•œ ์˜ˆ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
https://codesandbox.io/s/react-hook-form-controller-079xx?file=/src/index.js

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰