8월, 2026의 게시물 표시

Next.js Server Actions "Functions cannot be passed directly to Client Components" 에러 해결법

이미지
3초 요약: 이렇게 고치세요 원인: 서버 컴포넌트의 일반 함수는 직렬화가 안 돼서, Client Component에 props로 그대로 넘기면 React가 전달 자체를 막음 해결: 넘길 함수 내부 최상단에 'use server' 를 선언해 진짜 Server Action으로 만들거나, 서버 로직이 필요 없다면 아예 클라이언트 컴포넌트 안으로 로직을 옮기기 주의: 인자를 미리 고정해서 넘기고 싶으면 .bind(null, id) 로 감싸야지, 클로저로 감싼 일반 함수를 새로 만들면 다시 같은 에러가 남 async function deletePost(id: string) { 'use server'; await db.post.delete({ where: { id } }); } ↓ 왜 이런 에러가 나는지 원리 보기 서버 컴포넌트에서 만든 핸들러 함수를 버튼 같은 클라이언트 컴포넌트에 그대로 props로 넘기면 "Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with \"use server\"" 에러가 뜨는 경우가 있습니다. 왜 함수는 그냥 넘길 수 없는지와, Server Action으로 바꿔서 해결하는 방법을 정리합니다. 왜 서버 컴포넌트의 함수를 클라이언트 컴포넌트에 그대로 못 넘길까 서버 컴포넌트는 브라우저로 그대로 전송되지 않습니다. 서버에서 렌더링된 결과가 RSC(React Server Components) 페이로드라는 직렬화된 데이터 형태로 변환되어 클라이언트로 넘어가고, 클라이언트는 이 데이터를 읽어서 화면을 조립합니다. 이때 문자열, 숫자, 객체, 배열처럼 JSON으로 표현 가능한 값...

React Each child in a list should have a unique key prop 경고와 index key 버그

이미지
3초 요약: 이렇게 고치세요 원인: map() 으로 만든 목록의 최상위 요소에 key 를 주지 않아서 발생 — 화면을 다시 그릴 때 어떤 요소가 어떤 항목이었는지 React가 짝지을 근거가 없음 해결: 데이터가 원래 가진 고유 id를 key 로 사용 / 빈 태그로 감쌌다면 <Fragment key={...}> 로 바꿔서 지정 주의: 배열 index를 key 로 쓰면 경고는 사라지지만, 목록 순서가 바뀌거나 중간 항목이 삭제될 때 입력값·체크 상태가 엉뚱한 행에 남는 더 찾기 힘든 버그가 생김 {todos.map((todo) => ( <li key={todo.id}>{todo.text}</li> // index 말고 고유 id ))} ↓ 왜 이런 경고가 나는지 원리 보기 목록을 map() 으로 그리다 보면 콘솔에 'Warning: Each child in a list should have a unique "key" prop' 경고가 뜹니다. 화면은 멀쩡히 나오니 일단 넘어가기 쉬운데, 이 경고는 단순한 잔소리가 아니라 나중에 훨씬 찾기 어려운 버그로 되돌아오는 경우가 많습니다. React가 목록에 key를 요구하는 이유 React는 상태가 바뀔 때마다 화면 전체를 새로 그리는 대신, 이전 렌더링 결과와 새 결과를 비교해서 달라진 부분만 실제 DOM에 반영합니다. 이때 목록은 유독 까다로운 대상입니다. 항목이 추가되거나 삭제되거나 순서가 바뀌면, 새로 만들어진 요소 중 무엇이 이전의 어떤 요소와 같은 항목인지 판단할 근거가 필요하기 때문입니다. key 가 바로 그 근거입니다. React는 같은 key 를 가진 요소를 같은 항목으로 취급해서 DOM 노드와 그 안의 상태를 그대로 유지하고, key 가 사라지면 그 ...

React Objects are not valid as a React child 에러 원인과 해결법

이미지
3초 요약: 이렇게 고치세요 원인: JSX 중괄호 안에 문자열·숫자가 아닌 객체 를 그대로 넣어서 발생 — React는 객체를 화면에 어떻게 그려야 할지 알 수 없음 해결: 객체면 user.name 처럼 원시값 속성을 꺼내 쓰고 / 배열이면 .map() 으로 펼치고 / Date 면 toLocaleDateString() 으로 문자열 변환 주의: 에러 메시지의 found: object with keys {...} 부분에 실제 객체의 키가 찍히므로 범인을 특정하는 단서가 됨 — 단 Date 처럼 자체 속성이 없는 객체는 이 목록이 비어 보임 <p>{user}</p> {/* 에러 */} <p>{user.name}</p> {/* 정상 */} ↓ 왜 이런 에러가 나는지 원리 보기 잘 돌아가던 화면이 갑자기 하얗게 날아가면서 "Objects are not valid as a React child (found: object with keys {name, email})" 같은 에러가 뜬 적 있으실 겁니다. 원인은 대부분 간단합니다. JSX 중괄호 안에 문자열이나 숫자가 아닌 객체를 그대로 넣었기 때문인데, 정작 어느 줄이 범인인지 찾는 게 더 오래 걸리는 에러입니다. React가 객체를 화면에 그리지 못하는 이유 JSX의 중괄호는 그 안의 값을 화면에 출력하라는 뜻입니다. React는 여기에 들어온 값이 문자열이나 숫자면 텍스트 노드로 만들고, 배열이면 각 항목을 순회하고, React 엘리먼트면 그대로 렌더링합니다. 그런데 일반 객체가 들어오면 얘기가 달라집니다. { name: '김개발', email: 'dev@example.com' } 이라는 객체를 화면에 어떤 글자로 표시해야 할지는 React가 ...