React에서 필요한 Hook 정리

2025. 9. 8. 23:12·🖥️ Frontend/React

1️⃣ useState – 상태 관리

  • 용도: input, select, checkbox 등 값을 저장하고 변경
  • 특징: 값이 바뀌면 컴포넌트 리렌더링
import { useState } from "react";

export default function ExampleUseState() {
  const [formData, setFormData] = useState({}); // 초기값 없이 빈 객체 가능

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log("FormData:", formData); // 한 번에 formData 확인 가능
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="sText" placeholder="검색어" onChange={handleChange} />
      <input name="sPage" placeholder="페이지" onChange={handleChange} />
      <input name="sGubun" placeholder="구분" onChange={handleChange} />
      <button type="submit">Submit</button>
    </form>
  );
}

💡 JSP에서 hidden input + egovMap처럼 한 객체에 다 모아서 submit 가능.


2️⃣ useEffect – 컴포넌트 생명주기/사이드이펙트

  • 용도: 초기 데이터 로딩, API 호출, DOM 접근, 구독/해제
  • 특징: componentDidMount / componentDidUpdate / componentWillUnmount 역할
import { useState, useEffect } from "react";

export default function ExampleUseEffect() {
  const [data, setData] = useState([]);

  useEffect(() => {
    // 컴포넌트 마운트 시 데이터 로딩
    fetch("/api/board/list")
      .then(res => res.json())
      .then(json => setData(json));
  }, []); // [] → 마운트 시 1번만 실행

  return (
    <div>
      <h1>Board List</h1>
      <ul>
        {data.map(item => (
          <li key={item.boardId}>{item.title}</li>
        ))}
      </ul>
    </div>
  );
}

💡 JSP + Spring Controller에서 뿌리던 request.getAttribute 대신 API 호출 후 state에 저장.


3️⃣ useRef – DOM/값 직접 접근

  • 용도: input 값 직접 참조, 렌더링 없이 값 유지
  • 특징: submit 시점에만 값 확인, 불필요한 리렌더링 없음
import { useRef } from "react";

export default function ExampleUseRef() {
  const inputRef = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log("Input value:", inputRef.current.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input ref={inputRef} placeholder="검색어" />
      <button type="submit">Submit</button>
    </form>
  );
}

💡 JSP hidden input처럼 입력값을 submit 시점에 한 번만 사용할 때 유용.


4️⃣ useNavigate + useLocation (react-router-dom) – 페이지 이동/값 전달

  • 용도: List → Detail 페이지 이동, 이전 검색조건 전달
  • 특징: URL + state 전달 가능, React SPA 특화
// ListPage.jsx
import { useState } from "react";
import { useNavigate } from "react-router-dom";

export default function ListPage() {
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useState({});

  const handleChange = (e) => {
    const { name, value } = e.target;
    setSearchParams(prev => ({ ...prev, [name]: value }));
  };

  const goDetail = (boardId) => {
    navigate(`/detail/${boardId}`, { state: searchParams });
  };

  return (
    <div>
      <input name="sText" placeholder="검색어" onChange={handleChange} />
      <input name="sPage" placeholder="페이지" onChange={handleChange} />
      <button onClick={() => goDetail(123)}>상세보기</button>
    </div>
  );
}

// DetailPage.jsx
import { useLocation, useParams } from "react-router-dom";

export default function DetailPage() {
  const location = useLocation();
  const params = useParams();

  const { sText, sPage } = location.state || {};
  const { boardId } = params;

  return (
    <div>
      <h1>Detail Page</h1>
      <p>Board ID: {boardId}</p>
      <p>검색어: {sText}</p>
      <p>페이지: {sPage}</p>
    </div>
  );
}

💡 JSP에서 hidden input + egovMap으로 boardId + 검색조건 넘기던 패턴과 1:1 대응 가능.


5️⃣ Validation – 간단하게 처리

import { useState } from "react";

export default function ValidationExample() {
  const [email, setEmail] = useState("");
  const [error, setError] = useState("");

  const handleChange = (e) => {
    setEmail(e.target.value);
    setError(e.target.value.includes("@") ? "" : "올바른 이메일이 아닙니다.");
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    if(!email.includes("@")) {
      alert("이메일 확인 필요");
      return;
    }
    console.log("Submit:", email);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={email} onChange={handleChange} placeholder="email" />
      {error && <span style={{color:"red"}}>{error}</span>}
      <button type="submit">Submit</button>
    </form>
  );
}

💡 작은 폼은 useState + onChange로 실시간 validation, 큰 폼은 React Hook Form 추천


🔹Hook 용도 JSP 패턴 비교

useState input 상태 관리, formData <input> + hidden input + egovMap
useEffect 초기 데이터 호출, side effect <c:forEach> + JSP 초기 데이터 렌더링
useRef DOM 직접 접근, submit 시점 값 확인 hidden input, submit 시점 데이터
useNavigate / useLocation 페이지 이동, state 전달 form action + hidden input 전달
Validation 입력 실시간 확인 / submit 검증 server-side validation + JSTL/JavaScript

 

useState + handleChange

const [formData, setFormData] = useState({});
  • useState()는 React 컴포넌트에서 상태(state)를 저장할 때 사용
  • 여기서 formData = 상태값, 현재 form에 입력된 데이터를 담는 객체
  • setFormData = 상태를 바꾸는 함수, 이걸 호출하면 React가 컴포넌트를 다시 렌더링함
  • useState({}) → 초기값을 빈 객체로 시작

handleChange 분석

const handleChange = (e) => {
  const { name, value } = e.target;
  setFormData(prev => ({ ...prev, [name]: value }));
};

e.target

  • e는 이벤트 객체, 여기서는 input이 변경될 때 발생
  • e.target → 변경된 input DOM 요소
  • e.target.name → input의 name 속성
  • e.target.value → input에 입력된 값

const { name, value } = e.target;

  • JS 구조분해(destructuring)
  • name = e.target.name
  • value = e.target.value
  • 축약형 → 바꿔 쓰지 않아도 바로 변수로 사용 가능

setFormData(prev => ({ ...prev, [name]: value }))

  • prev = 이전 상태(formData의 이전 값)
  • ...prev = 이전 상태의 모든 key:value를 복사
  • [name]: value = 새로 입력된 값을 동적으로 key로 추가/갱신

예시:

// 초기 formData
formData = {}

// 사용자가 input name="sText", value="Hello" 입력
setFormData(prev => ({ ...prev, [name]: value }))
// prev = {}  
// ...prev = {} // 기존 값 없음
// [name]: value = sText: "Hello"
// 결과 → formData = { sText: "Hello" }
// 다음으로 input name="sPage", value="1" 입력
// prev = { sText: "Hello" }
setFormData(prev => ({ ...prev, [name]: value }))
// ...prev = { sText: "Hello" } // 기존 값 유지
// [name]: value = sPage: "1"
// 결과 → formData = { sText: "Hello", sPage: "1" }

💡 [name]: value + ...prev → 입력될 때마다 기존 상태는 유지하고, 새 값을 덮어쓰기


useEffect

useEffect(() => {
  fetch("/api/board/list")
    .then(res => res.json())
    .then(json => setData(json));
}, []);

useEffect = React에서 JSP의 init, JSTL 반복, 서버 초기 렌더링과 비슷한 역할

  • componentDidMount → [] 빈 배열 넣으면 처음 마운트될 때만 실행
  • componentDidUpdate → 배열에 상태 넣으면 특정 값이 바뀔 때 실행
  • componentWillUnmount → return 함수 사용 시 컴포넌트 제거 시 실행

fetch()

  • JS 내장 함수, 서버 API 호출
  • fetch(url) → 서버에서 데이터를 가져오는 요청
  • .then(res => res.json()) → 서버 응답을 JSON으로 변환
  • .then(json => setData(json)) → React 상태로 저장

[] 빈 배열 의미

  • [] → 의존성이 없음 → 마운트될 때 한 번만 실행
  • [formData]처럼 상태 넣으면 formData가 바뀔 때마다 다시 실행

useRef

const inputRef = useRef();
<input ref={inputRef} />
  • useRef = DOM에 직접 접근하거나, 렌더링과 무관하게 값 유지
  • 예: hidden input처럼 submit 시점에만 값을 읽고 싶을 때
  • inputRef.current.value → 현재 input DOM의 값
// submit 시점
console.log(inputRef.current.value);

💡 차이:

  • useState → 입력할 때마다 리렌더링
  • useRef → 값은 유지하지만 리렌더링 없음 → 성능 최적화용

useNavigate + useLocation (react-router-dom)

const navigate = useNavigate();
navigate(`/detail/${boardId}`, { state: searchParams });

useNavigate()

  • React Router v6에서 페이지 이동을 JS로 제어
  • JSP form의 action="/detail.do"와 비슷
  • URL 경로 이동 가능

state 옵션

  • state: searchParams → List 페이지에서 쌓은 검색 조건을 Detail 페이지로 전달
  • JSP에서 hidden input + egovMap처럼 한 객체를 그대로 전달 가능

DetailPage에서 받기

const location = useLocation();
const params = useParams();
const { sText, sPage } = location.state || {};
const { boardId } = params;
  • useLocation().state → List에서 전달한 검색 조건
  • useParams() → URL에 들어간 boardId 받기 (/detail/123)

Arrow Function => 의미

const handleChange = (e) => { ... }
  • 일반 함수:
function handleChange(e) { ... }
  • 축약 문법 → this 바인딩 없이 사용 가능
  • React에서 이벤트 처리 시 거의 항상 arrow function 사용

input name/value + prev 동작

  • prev = 이전 상태 객체
  • [name]: value → 입력한 input의 name 속성을 key로, 입력값을 value로 추가
  • ...prev → 기존 상태를 유지 (spread 문법)
  • 결과 = 입력될 때마다 formData가 점점 쌓이는 구조
formData = { sText: "Hello", sPage: "1", sGubun: "typeA" }

 

  1. useState → 상태 저장, 입력할 때마다 리렌더링
  2. useEffect → 컴포넌트가 마운트되거나 상태 바뀔 때 실행 (초기 데이터/API 호출)
  3. useRef → DOM 직접 접근, 렌더링 없이 값 유지
  4. useNavigate + useLocation → 페이지 이동 + 상태 전달 (JSP hidden input과 동일)
  5. prev + [name]: value → 여러 input을 한 객체(formData)에 자동으로 누적
  6. fetch() → 서버에서 JSON 데이터 가져오기
  7. => → 축약함수, this 없이 안전하게 사용

 

'🖥️ Frontend > React' 카테고리의 다른 글

React 입력값 처리 최적화: Debounce vs 클라이언트 필터링  (0) 2025.09.13
[React] JSX(TSX) 문법 정리  (0) 2025.08.20
'🖥️ Frontend/React' 카테고리의 다른 글
  • React 입력값 처리 최적화: Debounce vs 클라이언트 필터링
  • [React] JSX(TSX) 문법 정리
hjwjo
hjwjo
백엔드 및 풀스택 개발에 관심 있는 초보 개발자의 개발 블로그입니다.
  • hjwjo
    Jeongwoo's Devlog
    hjwjo
  • 전체
    오늘
    어제
    • Devlog N
      • 🗄️ Backend
        • Java
        • Spring
        • JPA
        • SQL
        • JSP
        • AWS
        • GCP
        • Linux
        • GitHub
        • ML
        • Security
      • 🖥️ Frontend N
        • React N
        • CSS
      • 🏅 Project
        • Hackathon
        • Team Project
      • 📊 Algorithm
        • BOJ
      • 📜 Certs
        • ADsP
        • SQLD
        • 정보처리기사
      • 📖
        • JavaScript
      • 일상
        • 면접후기
  • 블로그 메뉴

    • 홈
    • Devlog
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    jsp
    ADsP
    AWS
    springboot
    java기초
    자바
    GCP
    SQL
    java
    스프링
    DML
    쿼리
    백준
    데이터베이스
    정처기
    백엔드
    Spring
    스프링부트
    http
    정보처리기사
  • 최근 댓글

  • 최근 글

hjwjo
React에서 필요한 Hook 정리
상단으로

티스토리툴바