May 06, 2023
νλ‘ νΈμλ κ°λ°μμ μ μ₯μμ λ°μ΄ν°λ₯Ό λ€λ£¨λ λ°©λ²μ μ¬λ¬κ°μ§κ° μμ΅λλ€.
μ΄ μ€μ μ¬μ©μμ μ
λ ₯ κ° λ±μ λ°μ λ°μ΄ν°λ₯Ό μμ§νλ Form μ ν¨κ³Όμ μΌλ‘ μ μ΄ν μ μλ React-Hook-Form μ λν΄ μμλ³΄κ² λ ν
λ°μ.
κ·Έ μ μ μμ Form μ μ²λ¦¬νλλ° νμν μ¬μ μ§μμ μμ λ΄
λλ€.
νμν μ¬μ μ§μμ λ€μκ³Ό κ°μ΅λλ€.
κ°λ¨νκ² μ€λͺ νλ©΄ μ¬μ©μμ μ λ ₯μ μ²λ¦¬νλλ° React μ μν΄ κ°μ΄ μ μ΄λλ μ λ ₯ νΌ μ리먼νΈλ₯Ό μ μ΄ μ»΄ν¬λνΈλΌκ³ ν©λλ€.
https://ko.legacy.reactjs.org/docs/forms.html#controlled-components
μ¬μ©μμ μ λ ₯μ λ°λ μ»΄ν¬λνΈ (λνμ μΌλ‘ input) μ event κ°μ²΄λ₯Ό μ΄μ©ν΄ useState μ setState() ν¨μλ₯Ό ν΅ν΄ κ°μ μ μ΄νλ λ°©μμ μλ―Έν©λλ€. 리μ‘νΈμ μν΄ κ°μ΄ μ μ΄λκΈ°μ μ΄λ₯Ό μ μ΄ μ»΄ν¬λνΈλΌκ³ λΆλ¦ λλ€.
μ μ΄ μ»΄ν¬λνΈλ μ¬μ©μκ° μ λ ₯ν κ°κ³Ό μ μ₯λλ κ°μ΄ μ€μκ°μΌλ‘ λκΈ°ν λ©λλ€. μ¦ νμ μ΅μ κ°μ μ μ§νλλ°, μ΄λ μλ‘μ΄ μ λ ₯ κ°μ΄ μκΈΈ λλ§λ€ μνλ₯Ό μλ‘κ² κ°±μ ν©λλ€.
μ΄λ¬ν λ΄μ©λ€μ ꡬ체μ μΌλ‘ μ€λͺ νκΈ° μν΄ μ¬μ©μμ μ΄λ¦κ³Ό λΉλ°λ²νΈλ₯Ό λ°μ λ‘κ·ΈμΈμ κ°μ νλ μ»΄ν¬λνΈλ₯Ό λ§λ€μ΄ 보μμ΅λλ€.
μ΄ μ»΄ν¬λνΈλ₯Ό ν΅ν΄ μλ²μ μμ²μ λ³΄λΌ λ νμΈν΄μΌ ν μ¬νμ λ€μκ³Ό κ°μ΅λλ€.
μ΄λ₯Ό μν΄ νλ‘ νΈμλ κ°λ°μ νμν μ¬νμ λμ΄ν΄ λ³΄κ² μ΅λλ€.
μ΄λ¦, λΉλ°λ²νΈμ κ°μ μν κ΄λ¦¬νκΈ° μν κ°κ°μ state
const [username, setUsername] = useState<string>('')
const [password, setPassword] = useState<string>('')
μ΄λ¦, λΉλ°λ²νΈμ μλ¬ λ©μμ§ κ°μ μν κ΄λ¦¬νκΈ° μν κ°κ°μ state
const [usernameError, setUsernameError] = useState<string>('')
const [passwordError, setPasswordError] = useState<string>('')
μ΄λ¦, λΉλ°λ²νΈμ μ λ ₯κ°μ΄ λ³κ²½λλ μ΄λ²€νΈλ₯Ό κ΄λ¦¬νκΈ° μν onChange Handler ν¨μ
const handleUsernameChange = (
event: React.ChangeEvent<HTMLInputElement>
) => {
setUsername(event.target.value)
}
const handlePasswordChange = (
event: React.ChangeEvent<HTMLInputElement>
) => {
setPassword(event.target.value)
}
μ΄λ¦, λΉλ°λ²νΈμ μ ν©μ±μ νλ¨νλ validation ν¨μ
const validateName = (name: string) => {
let isValidated = false
if (name === '') {
setUsernameError('μ΄λ¦μ μ
λ ₯ν΄μ£ΌμΈμ.')
} else if (name.length < 2) {
setUsernameError('μ΄λ¦μ 2μ μ΄μ μ
λ ₯ν΄μ£ΌμΈμ.')
} else {
isValidated = true
setUsernameError('')
}
return isValidated
}
const validatePassword = (password: string) => {
let isValidated = false
if (password === '') {
setPasswordError('λΉλ°λ²νΈλ₯Ό μ
λ ₯ν΄μ£ΌμΈμ.')
} else if (password.length < 8) {
setPasswordError('λΉλ°λ²νΈλ 8μ μ΄μ μ
λ ₯ν΄μ£ΌμΈμ.')
} else {
isValidated = true
setPasswordError('')
}
return isValidated
}
μ΄λ¦, λΉλ°λ²νΈλ₯Ό κ°μ§κ³ API λ₯Ό μμ²νκΈ° μν onSubmit ν¨μ
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
const isValidatedName = validateName(username)
const isValidatedPassword = validatePassword(password)
if (isValidatedName && isValidatedPassword) {
console.log('username', username)
console.log('password', password)
setUsername('')
setPassword('')
setUsernameError('')
setPasswordError('')
}
}
μ μ΄ μ»΄ν¬λνΈλ‘ μ λ ₯κ°μ λ€λ£¨κΈ° μν΄μ κ°κ°μ μ λ ₯κ° λ§λ€ νλ νλ μνλ₯Ό μ μΈν΄ μ£Όκ³ , νΈλ€λ§ ν¨μλ₯Ό κ°λ³μ μΌλ‘ λ§λ€κ³ , μλ¬λ₯Ό μν μν, κ²μ¦μ μν ν¨μ λ±μ μ μ©νλλ° μ΄λ§νΌμ΄λ λ§μ μ½λλ€μ΄ μ¬μ©λ©λλ€.
λ¬Όλ‘ λ€μν μ λ ₯κ°λ€μ νλμ state κ°μ²΄λ₯Ό ν΅ν΄ κ΄λ¦¬νκ³ κ³΅ν΅μ μ΄λ²€νΈλ₯Ό κ΄λ¦¬νκΈ° μν onChange ν¨μλ₯Ό μλμ κ°μ΄ 리ν©ν λ§νμ¬ μ¬μ©ν μλ μμ΅λλ€.
const [inputs, setInputs] = useState({
username: '',
password: '',
})
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { value, name } = event.target
setInputs({
...inputs,
[name]: value,
})
}
νμ§λ§ μ λ ₯κ°μ΄ λ€μν΄μ§ μλ‘ (μ΄λ©μΌ, ν΄λμ ν, μ£Όμ λ±λ±) κ°μ λ°λ₯Έ validation λν λ€λ₯Ό κ²μ΄κ³ μλ΄μ νμν μλ¬λ©μμ§λ μΆκ°λμ΄μΌ ν κ²μ λλ€. μ΄λ¬ν μ λλ¬Έμ μμ±ν΄μΌ ν μ½λλ€μ΄ λ λ§μμ§κ³ onSubmit ν¨μμ λ‘μ§μ΄ 볡μ‘νκ³ λΉλν΄ μ§κ² λ κ²μ λλ€.
λ¨Όμ μμκ² μ§λ§ 리μ‘νΈμμ 리λ λλ§μ΄ λ°μνλ 쑰건μ λν΄ μμλ³΄κ³ λμ΄κ°κ² μ΅λλ€.
μμμ μμλ‘ μμ±ν μ μ΄ μ»΄ν¬λνΈμμλ λͺ¨λ κ°μ΄ state λ‘ κ°λ³ μ»΄ν¬λνΈμ μ°κ²°λμ΄ μμ΅λλ€. μ΄λ‘ μΈν΄ νλμ κ°μ΄ λ³ν λλ§λ€ μ¬λ¬ κ°μ μμ μ»΄ν¬λνΈ λ€μμ 무μν λ§μ 리λ λλ§μ΄ λ°μνκ² λ©λλ€.
μλ₯Ό λ€λ©΄ μ¬μ©μκ° username μ μ λ ₯κ°μ μ λ ₯νλ λμ λ€λ₯Έ μμ μ»΄ν¬λνΈ (μ: Selectbox, DatePicker λ±) λ±μ μ»΄ν¬λνΈκ° 리λ λλ§μ΄ λλ κ²½μ°λ₯Ό μλ―Ένλ©° μ΄λ λΆνμν λ λλ§μΌλ‘ μ±λ₯μμ μ΄μλ₯Ό μΌκΈ°ν μ μμ΅λλ€.
μμ μ€λͺ λλ Έλ―μ΄ μ μ΄ μ»΄ν¬λνΈλ νλ©΄μ μ λ ₯ν λ°μ΄ν°μ μνμ μ μ₯ν λ°μ΄ν°μ μνκ° νμ μΌμΉν©λλ€. μ΄ λ§μ μ¬μ©μκ° μ λ ₯νλ λͺ¨λ λ°μ΄ν°κ° λκΈ°ν λλ€λ μλ―ΈμΈλ°μ.
λ¨μ΄ νλ νλ μ λ ₯ν λλ§λ€ κ·Έ κ°μ΄ κ°±μ λμ΄ λ²λ¦¬κΈ° λλ¬Έμ λΆνμν 리λ λλ§, λΆνμν API μμ²μΌλ‘ μμ λλΉμ λ¬Έμ λ‘ μ°κ²°λ μλ μμ΅λλ€.
λΆνμν μμ² λ±μ λ°©μ§νκΈ° μν΄ μ€λ‘νλ§μ΄λ λλ°μ΄μ±μ μ¬μ©ν μ μλλ° form μ μμκ° μ¦κ°ν μλ‘ λͺ¨λ μ»΄ν¬λνΈμ μ€λ‘νλ§μ΄λ λλ°μ΄μ±μ κ±ΈκΈ°λ νλ€ μ μμ΅λλ€.
μ΄μ μλμ κ°μ κ°μ μ μν΄ λΉμ μ΄ μ»΄ν¬λνΈλ₯Ό μ¬μ©ν μ μκ³ κ·Έ λνμ μΈ λΌμ΄λΈλ¬λ¦¬ μ€ νλμΈ βreact-hook-formβ μ λν΄ μ€λͺ ν μκ°μ λλ€.
μλλ λΉμ μ΄ μ»΄ν¬λνΈμ λνμ μΈ νΉμ§μ λλ€. μμΈν μ€λͺ μ λ€μ κΈμμ μ΄μ΄ λκ° λ³΄κ² μ΅λλ€.
import React, { useState } from 'react'
const TestPage = () => {
const [username, setUsername] = useState<string>('')
const [password, setPassword] = useState<string>('')
const [usernameError, setUsernameError] = useState<string>('')
const [passwordError, setPasswordError] = useState<string>('')
const handleUsernameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
console.log(event.target.value)
setUsername(event.target.value)
}
const handlePasswordChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setPassword(event.target.value)
}
const validateName = (name: string) => {
let isValidated = false
if (name === '') {
setUsernameError('μ΄λ¦μ μ
λ ₯ν΄μ£ΌμΈμ.')
} else if (name.length < 2) {
setUsernameError('μ΄λ¦μ 2μ μ΄μ μ
λ ₯ν΄μ£ΌμΈμ.')
} else {
isValidated = true
setUsernameError('')
}
return isValidated
}
const validatePassword = (password: string) => {
let isValidated = false
if (password === '') {
setPasswordError('λΉλ°λ²νΈλ₯Ό μ
λ ₯ν΄μ£ΌμΈμ.')
} else if (password.length < 8) {
setPasswordError('λΉλ°λ²νΈλ 8μ μ΄μ μ
λ ₯ν΄μ£ΌμΈμ.')
} else {
isValidated = true
setPasswordError('')
}
return isValidated
}
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
const isValidatedName = validateName(username)
const isValidatedPassword = validatePassword(password)
if (isValidatedName && isValidatedPassword) {
console.log('username', username)
console.log('password', password)
setUsername('')
setPassword('')
setUsernameError('')
setPasswordError('')
}
}
return (
<section>
<h1 style={{ marginBottom: '12px' }}>μ μ΄ μ»΄ν¬λνΈμ μμμ
λλ€.</h1>
<form onSubmit={handleSubmit}>
<section>
<label htmlFor="username">μ¬μ©μ μ΄λ¦</label>
<input
id="username"
name="username"
type="text"
onChange={handleUsernameChange}
value={username}
/>
{usernameError && (
<span style={{ color: 'red' }}>{usernameError}</span>
)}
</section>
<section>
<label htmlFor="password">λΉλ°λ²νΈ</label>
<input
id="password"
name="password"
type="text"
onChange={handlePasswordChange}
value={password}
/>
{passwordError && (
<span style={{ color: 'red' }}>{passwordError}</span>
)}
</section>
<button>Login</button>
</form>
</section>
)
}
export default TestPage