2026. 6. 19.
초보자가 AI가 만든 버튼 안 눌릴 때 3분 체크 5가지
AI 코딩 도구가 만든 React 또는 Next.js 화면에서 버튼이 눌리지 않을 때 전체 코드를 다시 만들기보다 disabled 상태, onClick 연결, use client 경계, 콘솔 오류를 3분 안에 분리한다.

AI가 만든 화면에서 버튼이 보이는데 눌러도 아무 반응이 없으면 초보자는 곧바로 "버튼 고쳐줘"라고 다시 맡기기 쉽다. 그 순간부터 문제가 커진다. AI는 버튼 하나를 고치는 대신 컴포넌트 구조를 바꾸거나, 새 상태값을 만들거나, 관련 없는 파일까지 손댈 수 있다. 먼저 할 일은 다시 만들기가 아니라 버튼이 클릭을 받을 수 있는 상태인지 3분 안에 나누어 보는 것이다.
React 공식 문서(https://react.dev/learn/responding-to-events)는 클릭 같은 사용자 상호작용에 반응하려면 JSX 태그에 이벤트 핸들러 함수를 넘긴다고 설명한다. Next.js App Router에서는 상태 관리, 이벤트 처리, 브라우저 API가 필요한 UI에 클라이언트 컴포넌트 경계가 필요하다. 버튼 문제는 보통 "AI가 코드를 못 짰다"보다 더 작다. 버튼이 비활성화되어 있거나, onClick 이름이 잘못됐거나, 서버 컴포넌트와 클라이언트 컴포넌트 경계가 섞였거나, 콘솔에 이미 오류가 떠 있는 경우가 많다.
첫 30초에는 버튼이 클릭을 받을 수 있는 상태인지 본다
버튼이 눌리지 않을 때 가장 먼저 볼 것은 코드가 아니라 화면 상태다. 버튼 색이 흐리거나 커서가 바뀌지 않거나 로딩 문구가 계속 남아 있으면 disabled 상태일 수 있다. MDN의 HTMLButtonElement.disabled 문서(https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement/disabled)는 disabled가 켜진 컨트롤은 클릭을 받지 않는다고 설명한다. 초보자에게 이 한 줄은 중요하다. 클릭 함수가 틀린 것이 아니라 버튼이 애초에 클릭을 막고 있을 수 있기 때문이다.
브라우저에서 먼저 아래 세 가지를 본다.
- 버튼이 흐리게 보이거나 로딩 중으로 고정되어 있는가
- 버튼 위에 마우스를 올렸을 때 클릭 가능한 느낌이 있는가
- 입력값을 채우거나 체크박스를 누르면 버튼 상태가 바뀌는가
코드에서는 이런 부분을 찾는다.
<button disabled={isSubmitting || !title}>
저장하기
</button>
이 코드가 있다면 onClick을 보기 전에 isSubmitting과 title부터 확인해야 한다. AI에게 다시 물을 때도 "버튼 클릭이 안 돼요"라고만 쓰지 말고 이렇게 좁혀야 한다.
버튼이 disabled 상태로 보입니다.
아래 코드에서 어떤 값 때문에 disabled가 true로 유지되는지 먼저 찾아 주세요.
새 컴포넌트를 만들지 말고 현재 버튼과 상태값 연결만 확인해 주세요.
다음 1분에는 onClick이 함수로 연결됐는지 확인한다
React에서 버튼 클릭은 onClick에 함수를 넘겨야 작동한다. React 공식 문서는 onClick={handleClick}처럼 함수 자체를 넘기는 방식과 onClick={handleClick()}처럼 렌더링 중 바로 실행해 버리는 실수를 구분한다. 초보자는 두 코드를 비슷하게 보지만 결과는 다르다. 앞의 코드는 클릭할 때 실행되고, 뒤의 코드는 화면이 그려질 때 먼저 실행된다.
먼저 아래처럼 연결되어 있는지 본다.
function SaveButton() {
function handleSave() {
console.log("save clicked");
}
return <button onClick={handleSave}>저장하기</button>;
}
다음 코드는 다시 봐야 한다.
<button onclick={handleSave}>저장하기</button>
<button onClick={handleSave()}>저장하기</button>
<Button handleClick={handleSave}>저장하기</Button>
첫 번째는 React JSX에서 쓰는 onClick 대소문자가 아니다. 두 번째는 클릭 전에 함수를 실행한다. 세 번째는 직접 만든 Button 컴포넌트가 handleClick이라는 prop을 실제 <button onClick={...}>으로 넘기는지 확인해야 한다. AI가 디자인용 버튼 컴포넌트를 만들 때 이 연결이 빠지는 일이 있다.
Next.js라면 use client 경계를 좁게 붙인다
Next.js App Router에서 버튼 클릭, 상태 변경, 브라우저 API 사용이 필요한 컴포넌트는 클라이언트 쪽에서 실행되어야 한다. Next.js use client 문서(https://nextjs.org/docs/app/api-reference/directives/use-client)는 이 지시어가 클라이언트에서 렌더링될 컴포넌트의 진입점을 선언한다고 설명한다. 다만 모든 파일에 붙일 필요는 없다. 버튼이 들어 있는 작은 컴포넌트 파일에 경계를 두는 편이 보통 더 안전하다.
예를 들어 페이지 전체가 서버 컴포넌트여도 버튼만 분리할 수 있다.
// app/components/save-button.tsx
"use client";
export function SaveButton() {
function handleSave() {
console.log("clicked");
}
return <button onClick={handleSave}>저장하기</button>;
}
그리고 서버 페이지에서는 버튼 컴포넌트를 가져다 쓴다.
import { SaveButton } from "./components/save-button";
export default function Page() {
return (
<main>
<h1>게시글 작성</h1>
<SaveButton />
</main>
);
}
여기서 주의할 점은 서버 컴포넌트에서 만든 함수를 클라이언트 컴포넌트 prop으로 그대로 넘기지 않는 것이다. Next.js 문서는 클라이언트 컴포넌트의 props가 직렬화 가능한 형태여야 한다고 설명한다. 버튼 클릭 함수는 보통 클라이언트 컴포넌트 안에서 만들거나, 서버 액션처럼 별도 규칙이 있는 방식으로 다뤄야 한다.
콘솔 오류는 버튼 클릭보다 먼저 떠 있을 수 있다
버튼을 누르기 전에 이미 브라우저 콘솔에 오류가 떠 있으면 클릭 함수까지 가지 못한다. Chrome DevTools Console 문서(https://developer.chrome.com/docs/devtools/console)는 Console을 JavaScript 웹 앱 테스트와 디버그에 쓰며, 로그 메시지 확인과 JavaScript 실행이 주요 용도라고 설명한다. 초보자는 화면만 보지만, 버튼 문제에서는 콘솔 첫 오류가 더 빠른 단서가 된다.
확인 순서는 짧게 가져간다.
- 브라우저에서 F12를 누르고 Console을 연다.
- 페이지를 새로고침한다.
- 버튼을 누르기 전부터 빨간 오류가 있는지 본다.
- 버튼을 누른 직후 새 오류가 추가되는지 본다.
- 오류 문장과 파일 경로를 AI에게 같이 준다.
AI에게는 아래처럼 물으면 된다.
React/Next.js 화면에서 버튼이 눌리지 않습니다.
버튼 코드:
[버튼 컴포넌트 코드]
콘솔 오류:
[첫 오류 문장과 파일 경로]
확인해 주세요:
1. disabled가 true로 고정되는지
2. onClick이 함수로 연결되어 있는지
3. 직접 만든 Button 컴포넌트가 onClick을 실제 button까지 넘기는지
4. Next.js라면 use client 경계가 필요한지
5. 최소 수정 파일 1개만 제안할 수 있는지
이 요청문은 AI에게 새 화면을 만들라고 시키는 문장이 아니다. 현재 버튼이 왜 반응하지 않는지 원인을 분리하게 만드는 문장이다. 특히 마지막 줄의 "최소 수정 파일 1개"가 중요하다. 버튼 하나 때문에 페이지 전체가 바뀌는 일을 줄일 수 있다.
저장하기 전에는 5가지를 한 줄로 말할 수 있어야 한다
버튼을 고친 뒤 바로 저장하지 말고 30초만 더 쓴다. 아래 다섯 줄을 채우지 못하면 아직 원인을 이해하지 못한 상태다.
버튼 상태:
disabled 원인:
onClick 연결:
use client 필요 여부:
콘솔 오류 변화:
예시는 이렇게 쓸 수 있다.
버튼 상태: 입력값이 비어 있을 때 disabled였다.
disabled 원인: title 값이 빈 문자열이었다.
onClick 연결: handleSave가 button까지 전달됐다.
use client 필요 여부: SaveButton 파일에만 필요했다.
콘솔 오류 변화: 수정 뒤 새 오류가 생기지 않았다.
이 정도로 설명할 수 있으면 AI가 만든 코드를 그냥 믿는 단계에서 벗어난 것이다. 오늘 버튼이 눌리지 않는다면 전체 코드를 다시 만들기 전에 disabled, onClick, use client, 콘솔 오류, 최소 수정 범위를 순서대로 확인한다. 그 다음 AI에게 다시 맡기면 "고쳐줘"가 아니라 "이 원인을 기준으로 최소 수정해줘"라는 요청이 된다.
참고 출처
- React Responding to Events: https://react.dev/learn/responding-to-events
- Next.js use client directive: https://nextjs.org/docs/app/api-reference/directives/use-client
- MDN HTMLButtonElement disabled: https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement/disabled
- Chrome DevTools Console overview: https://developer.chrome.com/docs/devtools/console
다음으로 읽을 기사
같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.
첫 번째 댓글을 남겨보세요
여러분의 생각이 다른 독자에게 도움이 됩니다.
댓글 0
이 글을 읽은 독자들의 생각을 나눠보세요.