react 블로그에 매우 간단한 input 유효성 검사를 해보려고 했다.
e.target.value에 들어있는 값이 '' 이면 alert를 띄우려고 했는데, 이렇게 하면 전송버튼을 눌렀을 때 그대로 올라갔다.
의심되는 것은 input 이 아니라 button에서 검사했어야 하는 건가? 하는 부분이다. (다시 보니 진짜 당연한 건데)
어쨌든 궁금한 부분을 chatGPT한테 물어봤다.
기존 코드 :
function App(){
let [입력값, 입력값변경] = useState("");
// 중간 생략
<input
onChange={(e) => {
e.target.value == ""
? alert("내용을 입력해 주세요.")
: 입력값변경(e.target.value);
}}
/>
<button
onClick={() => {
let cpy = [...글제목];
cpy.push(입력값);
글제목변경(cpy);
let nalcpy = [...날짜];
nalcpy.push(today);
날짜변경(nalcpy);
let dcpy = [...따봉];
dcpy.push(뉴따봉);
따봉변경(dcpy);
}}
>
글쓰기
</button>
현재 코드에서 발생한 문제는 유효성 검사(입력값 체크)를 input의 onChange 이벤트에서 수행했기 때문이에요. 이로 인해 사용자가 입력 중일 때마다 alert가 뜨거나, 입력값이 없어도 버튼을 눌렀을 때 글이 발행됩니다. 하지만, 입력값 유효성 검사는 글쓰기 버튼을 클릭했을 때 수행해야 더 자연스럽습니다.
유효성 검사를 onChange에서 수행함
onChange는 사용자가 입력 필드에 무언가를 입력할 때마다 호출됩니다.onClick에서 유효성 검사를 하지 않음
onClick 이벤트는 유효성 검사 없이 바로 입력값을 배열(글제목, 날짜, 따봉)에 추가합니다.onClick 이벤트에서 수행유효성 검사를 글쓰기 버튼(onClick)에서 실행하도록 변경하면, 입력값이 없을 때만 경고를 띄우고 글을 발행하지 않게 만들 수 있습니다.
수정된 App 컴포넌트 코드는 아래와 같습니다:
import React, { useState } from "react";
function App() {
const [입력값, 입력값변경] = useState("");
const [글제목, 글제목변경] = useState([]);
const [날짜, 날짜변경] = useState([]);
const [따봉, 따봉변경] = useState([]);
const today = new Date().toLocaleDateString(); // 오늘 날짜
const 뉴따봉 = 0; // 초기 따봉 값
return (
<div className="App">
<input
onChange={(e) => {
입력값변경(e.target.value);
}}
value={입력값} // 입력값을 input에 반영
placeholder="글 제목을 입력하세요"
/>
<button
onClick={() => {
// 입력값이 비어 있는지 검사
if (입력값.trim() === "") {
alert("내용을 입력해 주세요."); // 경고 메시지 출력
return; // 함수 종료
}
// 글 발행 처리
let cpy = [...글제목];
cpy.push(입력값);
글제목변경(cpy);
let nalcpy = [...날짜];
nalcpy.push(today);
날짜변경(nalcpy);
let dcpy = [...따봉];
dcpy.push(뉴따봉);
따봉변경(dcpy);
// 입력값 초기화
입력값변경("");
}}
>
글쓰기
</button>
{/* 글 리스트 출력 */}
{글제목.map((title, index) => (
<div key={index}>
<h4>{title}</h4>
<p>{날짜[index]}</p>
<p>따봉: {따봉[index]}</p>
</div>
))}
</div>
);
}
export default App;
onClick 이벤트에서 아래와 같이 입력값이 비어 있는지 검사합니다:
if (입력값.trim() === "") {
alert("내용을 입력해 주세요."); // 경고 메시지 출력
return; // 함수 종료
}
입력값.trim()은 입력값의 앞뒤 공백을 제거한 문자열을 반환합니다. 공백만 입력해도 경고를 띄우기 위함입니다.alert를 띄운 뒤 글 발행 로직을 실행하지 않도록 return으로 함수를 종료합니다.onChange 이벤트에서 입력값 관리onChange는 단순히 입력값을 입력값 상태에 반영하기만 하면 됩니다. 이렇게 하면 입력값 상태는 사용자가 입력한 내용을 항상 최신 상태로 유지합니다.
<input
onChange={(e) => {
입력값변경(e.target.value);
}}
value={입력값} // 입력값을 input에 반영
placeholder="글 제목을 입력하세요"
/>
글이 성공적으로 발행된 후, 입력값을 빈 문자열로 초기화하여 입력 필드도 비워줍니다:
입력값변경("");
글제목, 날짜, 따봉 배열을 사용해 글 리스트를 화면에 출력합니다. 아래 코드로 구현할 수 있습니다:
{글제목.map((title, index) => (
<div key={index}>
<h4>{title}</h4>
<p>{날짜[index]}</p>
<p>따봉: {따봉[index]}</p>
</div>
))}
map을 사용해 배열의 각 항목을 컴포넌트로 변환하고, key 속성으로 고유 식별자를 지정합니다.날짜와 따봉 배열에서도 동일한 인덱스를 사용해 데이터를 출력합니다.alert("내용을 입력해 주세요.")가 출력됩니다.글 제목이 너무 길지 않도록 제한을 걸 수 있습니다. 예를 들어, 글 제목이 50자 이상이라면 경고를 띄우도록 구현할 수 있습니다:
if (입력값.length > 50) {
alert("글 제목은 50자 이내로 작성해 주세요.");
return;
}
유효성 검사 로직이 복잡해질 경우, 이를 별도의 함수로 분리하여 코드 가독성을 높일 수 있습니다:
const validateInput = (input) => {
if (input.trim() === "") {
alert("내용을 입력해 주세요.");
return false;
}
if (input.length > 50) {
alert("글 제목은 50자 이내로 작성해 주세요.");
return false;
}
return true;
};
<button
onClick={() => {
if (!validateInput(입력값)) return;
// 글 발행 처리...
}}
>
글쓰기
</button>
onClick 이벤트에서 처리해야 적합합니다.onChange는 입력값을 상태에 반영하기만 하면 됩니다.