2026. 7. 2.

React 체크박스가 안 눌릴 때, 3분 안에 checked부터 고치는 순서

AI가 만든 React 설정 화면에서 체크박스를 눌러도 체크 표시가 바뀌지 않을 때, 컴포넌트 전체를 다시 만들기 전에 checked, onChange, e.target.checked, preventDefault, label 연결을 3분 안에 확인하는 순서입니다.

3 min read
React 체크박스가 안 눌릴 때, 3분 안에 checked부터 고치는 순서 대표 이미지

AI가 만든 알림 설정 화면, 약관 동의 화면, 필터 패널에서 체크박스를 눌렀는데 표시가 그대로 멈출 때가 있습니다. 버튼도 있고 화면도 그럴듯해서 더 헷갈립니다. 초보자 입장에서는 "체크박스 하나 때문에 컴포넌트를 전부 다시 만들어야 하나"라는 생각이 먼저 듭니다.

대부분은 전체 재작성 문제가 아닙니다. React 체크박스는 checked 값과 onChange가 같은 상태를 보고 있어야 안정적으로 움직입니다. 오늘 목표는 화면을 새로 만드는 것이 아니라 체크 표시가 멈춘 지점을 3분 안에 좁히는 것입니다.

React 체크박스가 checked, onChange, state 흐름으로 갱신되는 구조

react.dev의 React 공식 <input> 문서는 체크박스나 라디오 버튼을 제어할 때 checked가 선택 여부를 제어하고, 제어 입력에는 전달한 값을 동기적으로 갱신하는 onChange가 필요하다고 설명합니다. 또 체크박스에는 value가 아니라 checked 또는 defaultChecked가 맞다고 정리합니다. developer.mozilla.org의 MDN checkbox 문서도 HTML의 value는 제출될 문자열이고, 현재 선택 상태는 checked 쪽에서 다뤄야 한다고 구분합니다. 그래서 이 문제는 "클릭 이벤트가 있나"보다 "현재 체크 상태를 어디서 읽고 어디에 저장하나"가 핵심입니다.

30초 안에 checked만 있고 onChange가 빠졌는지 봅니다

먼저 문제가 되는 체크박스 줄을 찾습니다. 초보자가 가장 자주 만나는 모양은 checked는 있는데 상태를 바꾸는 함수가 없는 코드입니다.

<input type="checkbox" checked={emailEnabled} />

이 코드는 화면에 체크 상태를 보여 주지만, 사용자가 클릭했을 때 그 값을 바꾸는 통로가 없습니다. React가 emailEnabled 값을 기준으로 입력을 제어하고 있는데 emailEnabled를 바꾸는 코드가 없으니, 클릭해도 다시 원래 값으로 돌아온 것처럼 보입니다.

수정은 작게 합니다.

const [emailEnabled, setEmailEnabled] = useState(false);

return (
  <label>
    <input
      type="checkbox"
      checked={emailEnabled}
      onChange={(e) => setEmailEnabled(e.target.checked)}
    />
    이메일 알림 받기
  </label>
);

여기서 중요한 줄은 하나입니다. 체크박스는 e.target.checked를 상태에 넣어야 합니다. e.target.value를 넣으면 "on" 같은 문자열을 다루게 되어, 나중에 조건문이나 저장 로직에서 예상과 다른 결과가 생길 수 있습니다.

1분 안에 value와 defaultChecked를 구분합니다

AI가 HTML 예시를 섞어 만들면 체크박스에 value를 붙이고 그 값을 상태처럼 쓰는 코드가 나올 수 있습니다.

<input
  type="checkbox"
  value={emailEnabled}
  onChange={(e) => setEmailEnabled(e.target.value)}
/>

이 코드는 "체크됐는가"를 보려는 목적과 맞지 않습니다. checkbox의 value는 폼이 제출될 때 서버로 보낼 문자열에 가깝고, 현재 체크 여부는 checked로 읽는 편이 맞습니다.

반대로 React가 체크 상태를 계속 관리할 필요가 없고, 처음에만 체크된 상태로 보여 주면 되는 경우에는 defaultChecked를 쓸 수 있습니다.

<input type="checkbox" defaultChecked={true} />

판단 기준은 간단합니다. 체크 여부로 버튼을 켜거나, 저장할 설정 값을 만들거나, 다른 UI를 바꿔야 한다면 checkedonChange를 씁니다. 처음 표시만 필요하고 React state로 추적하지 않아도 된다면 defaultChecked를 씁니다. 상태를 읽어야 하는 체크박스라면 defaultChecked로 끝내지 않습니다.

2분 안에 preventDefault 위치를 확인합니다

코드에 onClick, onMouseDown, 부모 form 이벤트가 함께 있으면 preventDefault()가 체크 동작을 막는 경우가 있습니다. developer.mozilla.org의 MDN preventDefault() 문서는 이 메서드가 브라우저의 기본 동작을 취소한다고 설명합니다. 체크박스 클릭의 기본 동작은 체크 상태를 바꾸는 것입니다.

function handleClick(e) {
  e.preventDefault();
}

return (
  <input
    type="checkbox"
    checked={emailEnabled}
    onClick={handleClick}
    onChange={(e) => setEmailEnabled(e.target.checked)}
  />
);

이런 코드를 보면 먼저 체크박스의 onClick에서 preventDefault()를 빼고 테스트합니다. 제출 새로고침을 막아야 한다면 보통 체크박스 클릭이 아니라 formonSubmit에서 처리하는 편이 명확합니다.

function handleSubmit(e) {
  e.preventDefault();
  saveSettings({ emailEnabled });
}

핵심은 preventDefault()를 모두 없애라는 말이 아닙니다. 체크 상태를 바꾸는 기본 동작을 막는 위치에 있는지를 보는 것입니다.

React 체크박스 안 눌림을 확인하는 5가지 체크리스트

3분 안에 label과 상태 이름을 맞춥니다

체크박스 자체는 잘 동작하지만, 사용자는 작은 네모칸 대신 옆의 글자를 누르는 경우가 많습니다. label 안에 input을 넣거나 htmlForid를 맞추면 글자를 눌러도 같은 입력과 연결됩니다.

<label htmlFor="emailEnabled">이메일 알림 받기</label>
<input
  id="emailEnabled"
  type="checkbox"
  checked={emailEnabled}
  onChange={(e) => setEmailEnabled(e.target.checked)}
/>

그다음 상태 이름을 봅니다. 아래처럼 checkedemailEnabled를 보는데 onChange는 다른 상태를 바꾸면 화면은 움직이지 않는 것처럼 보일 수 있습니다.

<input
  type="checkbox"
  checked={emailEnabled}
  onChange={(e) => setMarketingEnabled(e.target.checked)}
/>

수정은 어렵지 않습니다. checked가 읽는 상태와 onChange가 바꾸는 상태를 같은 이름으로 맞춥니다.

AI에게는 전체 재작성보다 좁은 수정을 요청합니다

AI에게 "체크박스가 안 됩니다. 고쳐 주세요"라고만 말하면 컴포넌트 전체를 다시 작성할 수 있습니다. 그러면 원래 맞던 CSS, 저장 함수, API 호출까지 같이 바뀔 수 있습니다. 아래처럼 범위를 좁혀 요청합니다.

AI에게 React 체크박스 오류를 최소 범위로 고치게 하는 프롬프트 카드
아래 React 컴포넌트에서 체크박스를 눌러도 UI 상태가 바뀌지 않습니다.

요청:
- 전체 컴포넌트를 다시 작성하지 말고 체크박스 관련 줄만 확인해 주세요.
- checked, onChange, e.target.checked 연결을 먼저 봐 주세요.
- preventDefault가 체크 기본 동작을 막는 위치에 있는지도 확인해 주세요.
- 수정 전후 차이를 짧게 설명해 주세요.

문제 코드:
[체크박스가 들어 있는 컴포넌트 전체를 붙여 넣기]

이 요청의 핵심은 수정 범위를 좁히는 것입니다. AI가 고칠 영역을 작게 잡으면 원래 되던 화면 구조를 덜 건드립니다.

마지막에 5가지만 다시 눌러 봅니다

수정 뒤에는 코드만 보지 말고 같은 화면에서 실제로 눌러 봅니다.

1. 클릭하면 체크 표시가 바로 바뀌는가
2. React state 값도 true/false로 바뀌는가
3. onChange에서 e.target.checked를 읽는가
4. 체크박스 클릭 위치에 preventDefault가 남아 있지 않은가
5. label 글자를 눌러도 체크 상태가 바뀌는가

여기까지 통과하면 체크박스 문제의 큰 원인은 사라집니다. 저장 버튼을 눌렀는데 서버에 반영되지 않는 문제는 다음 단계입니다. 지금 글에서 해결하는 범위는 "React 화면에서 체크박스를 눌렀는데 체크 상태가 바뀌지 않는 상황"입니다. 오늘은 체크박스가 멈추면 checked, onChange, e.target.checked부터 본다는 기준만 가져가면 됩니다.

참고 출처

다음으로 읽을 기사

같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.

댓글 0

이 글을 읽은 독자들의 생각을 나눠보세요.

비밀번호(선택)

첫 번째 댓글을 남겨보세요

여러분의 생각이 다른 독자에게 도움이 됩니다.