묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨아바타 커뮤니티앱 만들기 (React Native Expo)
layout tab 설정 문의.
탭 설정 관련 문의 드립니다.현재 디렉토리는 아래 이미지와 같은 구조이고, 하단의 스크립트처럼 Tab 설정에는 Home / Profile / setting 3가지가 명시 된 상태인데 이전 미션에서 작성한 mission.tsx가 하나의 탭으로 잡히고 있습니다.RN 구조상 (tabs) 디렉토리 하단에 파일들이 자동으로 탭으로 잡히는 구조인지, 별도의 설정으로 뺄 수 있는지 알수 있을까요?? export default function TabLayout() { return ( <Tabs screenOptions={{ tabBarActiveTintColor: "black", headerShown: false, }} > <Tabs.Screen name="index" options={{ title: "Home", }} /> <Tabs.Screen name="my" options={{ title: "Profile", }} /> <Tabs.Screen name="setting" options={{ title: "setting", }} /> </Tabs> ); }
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
querydsl QTodo관련 문의
안녕하세요. 강의를 듣다가 QTodo 사용하는 시점에서 문제가 발생하여 문의드립니다. gradle 빌드시점에 QTodo 클래스를 생성하는 것 까진 확인을 하였는데 search1 메소드에서 QTodo를 사용하려고 하니 클래스 인식 자체를 못하고 있습니다.(import도 안됨) 강의 내용상으로 봤을 때 build 디렉토리에서 인위적으로 복사한 것 같진 않은데 해당 클래스를 어떻게 import해서 사용해야 할지 몰라서 문의드립니다. springboot 버전은 3.3.10입니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
궁금한 점 질문 드립니다!
안녕하세요. 질문 있습니다.userAgent에 있는 값을 사용하고 싶습니다. 서버 측에서는 next/header 함수를 통해서 클라이언트 측에서는 네비게이터의 userAgent 객체를 사용하면 될 것 같은데 이 값을 사용하는 함수는 클라이언트, 서버 양쪽에서 실행됩니다.서버인지 클라이언트인지 분기 처리 후 값을 가져오고 싶었는데 next/header를 사용하는 파일을 import 하기만 해도 클라이언트 측에서는 에러가 나더라고요.이런 상황에서는 어떻게 해결해 나가는게 좋을까요? 감사합니다.
-
해결됨코드로 배우는 React 19 with 스프링부트 API서버
todo list 검색 기능 문의
todo list 에서 검색어를 입력하여 검색된 결과를 화면에 출력하려면 어떻게 구현해야 하는지요?예제에는 이런 것이 없는 거 같은데 제가 대충봐서 잘못 이해하고 있는 건가요?전체적인 흐름으로 설명해주시면 감사하겠습니다.
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
travel seller가 캐싱되지 않습니다.
fetchTravelproducts에서 클릭으로 상세 페이지로 들어가면 fetchTravelproduct 의 data 값을 보여주는데API 요청에서 data 값을 확인하면 seller 값이 들어있는데 data.fetchTravelproduct.seller를 콘솔에 찍으면 null 이 뜹니다. (다른 데이터는 정상적으로 불러옵니다.) fetchTravelproducts에서는 판매자 이름이 잘 출력이 되는데 상세페이지에 들어가면 해당 fetchTravelproduct API 요청으로 가져와도 판매자 데이터가 없는 상태로 뜨는데 문제가 뭘까요?여기서 상세페이지에서 새로고침을 하면 정상적으로 판매자가 보여집니다. fetchTravelproducts에서 캐싱하는 과정에 문제가 있는 걸 까요? // 상세 페이지 import { Query } from "@/entities/api/graphql"; import { gql, useQuery } from "@apollo/client"; export const TRAVEL_PRODUCT = gql` query fetchTravelproduct($travelproductId: ID!) { fetchTravelproduct(travelproductId: $travelproductId) { _id name remarks contents price tags images pickedCount travelproductAddress { zipcode address addressDetail lat lng } seller { _id name picture } createdAt } } `; export const useFetchTravelProduct = ({ travelId }: { travelId: string }) => { const result = useQuery<Pick<Query, "fetchTravelproduct">>(TRAVEL_PRODUCT, { variables: { travelproductId: travelId }, }); return result; };// 목록 페이지 import { Query } from "@/entities/api/graphql"; import { gql, useQuery } from "@apollo/client"; const TRAVEL_PRODUCTS = gql` query fetchTravelproducts($isSoldout: Boolean, $search: String, $page: Int) { fetchTravelproducts(isSoldout: $isSoldout, search: $search, page: $page) { _id name remarks contents price tags images pickedCount travelproductAddress { zipcode address addressDetail lat lng } buyer { _id name picture } seller { _id name picture } createdAt } } `; interface UseFetchTravelProductsArgs { isSoldout: boolean; search: string | null; page: number; } export const useFetchTravelProducts = ({ isSoldout, search, page, }: UseFetchTravelProductsArgs) => { const result = useQuery<Pick<Query, "fetchTravelproducts">>(TRAVEL_PRODUCTS, { variables: { isSoldout, search, page, }, }); return result; };
-
미해결Next.js 완벽 마스터 (v15): 노션 기반 개발자 블로그 만들기 (with 커서AI)
Docs 추가한 게 자꾸 사라져요
안녕하세요 선생님! 친절한 설명과 함께 강의 잘 듣고 있습니다. 강의교안에 링크로 남겨주신 것들 Cursor AI 설정에 Docs로 추가시에 add 한 것들이 자꾸만 사라지는 오류가 있습니다. 이전 강의에서도 사라지는 오류가 있을 때 재시도 하면 괜찮다고 하셔서 여러 번 시도했는데, 자꾸만 사라지네요 ㅠㅠ 뭔가 설정상의 문제가 있을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
js 핸드폰 인증번호 구현
여기서 time=time-1 붙였는데시간1초씩줄어드는거 적용이 안되요 도와주세요 ㅠㅠ
-
미해결실무에 바로 적용하는 스토리북과 UI 테스트
tailwind 4.x 버전 변경된 CSS 추출(?) 커맨드
강의에 있는 커맨드가 사용되지 않아서 이곳 저곳 돌아다니다가 발견했네요 npx @tailwindcss/cli -i ./src/index.css -o ./src/output.css --watch
-
미해결한 입 크기로 잘라먹는 Next.js(v15)
데이터 통신에 실패한 경우에 보여주는 페이지도 og를 설정해주는게 좋을까요?
안녕하세요!2-19에서 og태그를 통한 SEO 설정에서 궁금한 점이 생겼습니다.강의 마지막에 페이지가 fallback 되는 동안 보여줄 컴포넌트에서도 Head컴포넌트를 새로 만들어 og태그를 설정해주라고 설명해주셨는데, 데이터를 못 받아서 book에 null값을 받은 경우에 보여주는 페이지에선 og태그를 설정해줄 필요가 없을까요?검색엔진에 노출되기 위해 og태그를 페이지마다 입력해줘야 한다면 이런 오류 페이지에도 og태그를 설정해줘야 할 거 같아서요!
-
미해결React 완전 끝내기: useHoooooook
React 완전 끝내기: useHoooooook / seCallback 사용 배경 / name 변수가 무엇인지 알수있을까요?
name 이 선언되어있지않아서 실행시 에러가납니다
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
질문 있습니다.
만약 앱라우터에서 로컬 스토리지 사용 시, 클라이언트 컴포넌트에서 사용할 것이고 서버에는 없는 데이터가 클라이언트인 브라우저에는 있을수도 있을 것 같은데 이 경우 어떻게 해결하는게 보편적인가요? 생각나는건 하이드레이션 에러를 무시하는 프로퍼티가 있었던 것 같은데 이 방법은 안좋을 것 같고, 동적으로 클라이언트에서만 렌더링 하던가 같은 방법으로 Suspense로 묶어서 클라이언트에서만 렌더링 되게 하는 방법이 있을 것 같은데 강사님 생각이 궁금해 질문 드립니다. 항상 감사합니다!
-
미해결Next + React Query로 SNS 서비스 만들기
/compose/tweet 바로접속(새로고침) 에도 모달창 뜨게 하기
안녕하세요 질문드릴게 있습니다.'/compose/tweet' 모달창은 인터셉팅 라우트 + 페럴렐 라우트로 CSR 통한 접속은 잘 모달이 뜹니다.->(버튼을 클릭해서 모달창 뜨는 것을 말합니다.)하지만 만약 바로 URL직접 입력했을 때 (혹은 새로고침) 할 때는 뜨지 않습니다. 인터셉팅이 되지 않으니import Home from "@/app/(afterLogin)/home/page"; // (afterLogin)/compose/tweet export default function Page() { return <Home />; } 아마 여기서 Home에서 구현한 것만 뜨고, 모달로 구현한 것은 뜨지 않는 것 같습니다.하지만 실제 트위터에서는 바로 모달창이 뜨는 형태로 됩니다.어떻게 하면 새로고침/바로URL접속 에도 compose/tweet/ 모달창이 뜨게 할 지 조언을 구해봅니다.(직접 뒤에 배경 + 별도의 모달창을 바로 띄우는 생각은 했지만 다른 방식이 있는지 궁금합니다)import Home from "@/app/(afterLogin)/home/page"; import TweetModal from "../../@modal/(.)compose/tweet/page"; export default function Page() { return ( <> <Home /> <TweetModal /> </> ); } 버전은 15.3.0 입니다. 현재 사용하고 있는 폴더 구조는 아래와 같습니다.📦src ┣ 📂app ┃ ┣ 📂(afterLogin) ┃ ┃ ┣ 📂@modal ┃ ┃ ┃ ┣ 📂(.)compose ┃ ┃ ┃ ┃ ┗ 📂tweet ┃ ┃ ┃ ┃ ┃ ┣ 📜modal.module.css ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┃ ┣ 📂[username] ┃ ┃ ┃ ┃ ┣ 📂status ┃ ┃ ┃ ┃ ┃ ┗ 📂[id] ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂photo ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📂[photoId] ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜page.tsx ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜photoModal.module.css ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜default.tsx ┃ ┃ ┃ ┃ ┗ 📜default.tsx ┃ ┃ ┃ ┗ 📜default.tsx ┃ ┃ ┣ 📂[username] ┃ ┃ ┃ ┣ 📂status ┃ ┃ ┃ ┃ ┗ 📂[id] ┃ ┃ ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CommentForm.tsx ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜commentForm.module.css ┃ ┃ ┃ ┃ ┃ ┣ 📂photo ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📂[photoId] ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┃ ┃ ┃ ┣ 📜page.tsx ┃ ┃ ┃ ┃ ┃ ┗ 📜singlePost.module.css ┃ ┃ ┃ ┣ 📜page.tsx ┃ ┃ ┃ ┗ 📜profile.module.css ┃ ┃ ┣ 📂_components ┃ ┃ ┃ ┣ 📜ActionButtons.tsx ┃ ┃ ┃ ┣ 📜BackButton.tsx ┃ ┃ ┃ ┣ 📜FollowRecommand.tsx ┃ ┃ ┃ ┣ 📜LogoutButton.tsx ┃ ┃ ┃ ┣ 📜NavMenu.tsx ┃ ┃ ┃ ┣ 📜Post.tsx ┃ ┃ ┃ ┣ 📜PostArticle.tsx ┃ ┃ ┃ ┣ 📜PostImages.tsx ┃ ┃ ┃ ┣ 📜RightSearchZone.tsx ┃ ┃ ┃ ┣ 📜SearchForm.tsx ┃ ┃ ┃ ┣ 📜Trend.tsx ┃ ┃ ┃ ┣ 📜TrendSection.tsx ┃ ┃ ┃ ┣ 📜followRecommend.module.css ┃ ┃ ┃ ┣ 📜logout.module.css ┃ ┃ ┃ ┣ 📜navMenu.module.css ┃ ┃ ┃ ┣ 📜post.module.css ┃ ┃ ┃ ┣ 📜rightSearchZone.module.css ┃ ┃ ┃ ┣ 📜trend.module.css ┃ ┃ ┃ ┗ 📜trendSection.module.css ┃ ┃ ┣ 📂compose ┃ ┃ ┃ ┗ 📂tweet ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂explore ┃ ┃ ┃ ┣ 📜explore.module.css ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂home ┃ ┃ ┃ ┣ 📂_components ┃ ┃ ┃ ┃ ┣ 📜PostForm.tsx ┃ ┃ ┃ ┃ ┣ 📜Tab.tsx ┃ ┃ ┃ ┃ ┣ 📜TabProvider.tsx ┃ ┃ ┃ ┃ ┣ 📜postForm.module.css ┃ ┃ ┃ ┃ ┗ 📜tab.module.css ┃ ┃ ┃ ┣ 📜home.module.css ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂messages ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂search ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┗ 📜Tab.tsx ┃ ┃ ┃ ┣ 📜page.tsx ┃ ┃ ┃ ┗ 📜search.module.css ┃ ┃ ┣ 📜layout.module.css ┃ ┃ ┗ 📜layout.tsx ┃ ┣ 📂(beforeLogin) ┃ ┃ ┣ 📂@modal ┃ ┃ ┃ ┣ 📂(.)i ┃ ┃ ┃ ┃ ┗ 📂flow ┃ ┃ ┃ ┃ ┃ ┣ 📂login ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┃ ┃ ┃ ┗ 📂signup ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┃ ┗ 📜default.tsx ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┣ 📜LoginModal.tsx ┃ ┃ ┃ ┣ 📜Main.tsx ┃ ┃ ┃ ┣ 📜SignupModal.tsx ┃ ┃ ┃ ┣ 📜login.module.css ┃ ┃ ┃ ┣ 📜main.module.css ┃ ┃ ┃ ┗ 📜signup.module.css ┃ ┃ ┣ 📂i ┃ ┃ ┃ ┗ 📂flow ┃ ┃ ┃ ┃ ┣ 📂login ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┃ ┃ ┗ 📂signup ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂login ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📜layout.tsx ┃ ┃ ┣ 📜page.module.css ┃ ┃ ┗ 📜page.tsx ┃ ┣ 📜favicon.ico ┃ ┣ 📜globals.css ┃ ┣ 📜layout.tsx ┃ ┗ 📜not-found.tsx ┣ 📂components ┃ ┗ 📜RecordChangePathComponent.tsx ┗ 📂util ┃ ┗ 📜getBeforePath.ts
-
해결됨Next.js와 yolov11로 화재감지 시스템 구축하기
pnpm install is not found 오류
훤@□□□□ MINGW64 /c/LeeHwon/FlameGuard/FlameGuard/frontend (main)$ pnpm installbash: pnpm: command not found 이렇게 안 뜨는 이유가 무엇일까요..
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
Js 문자열 헷갈립니다ㅠ
js 공부중인데 여기서 aa 와 "aa"결과값이 다르게 나오는데 1.이유가 뭔가요? 2.둘 차이점이 뭔가요?자세하게 부탁드립니다 ㅠㅠ
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
노션에서 즐겨찾기가 안됩니다.
수업 노트 보기에서 노션에 들어가면 따로 즐겨찾기를 할 수 있는 기능이 없는데 어떻게 해야 되나요?
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
JWT와 @PreAuthorize 사용하기에서 권한오류
동영상 강의에 있는 내용대로 ProductController에서 @GetMapping("/list")에 @PreAuthorize("hasAnyRole('ROLE_USER','ROLE_ADMIN')")를 작성하고나서 postman에 login 후 accessToken을 가져와서 get방식으로 토큰을 넣어서 입력하면 status : 500, "error": Interner Server Error가 뜹니다.. @PreAuthorize부분을 주석처리하고 실행해보면 list값이 잘 나오네요.. 어디부분이 잘못 된걸까요?? 참고로 CustomSecurityConfig클래스에 @EnableMethodSecurity추가도 했습니다.@PreAuthorize("hasAnyRole('ROLE_USER','ROLE_ADMIN')") @GetMapping("/list") public PageResponseDTO<ProductDTO> list(PageRequestDTO pageRequestDTO){ return productService.getList(pageRequestDTO); } 여기가 ProductController 클래스 package org.zerock.apiserver.security.filter; import com.google.gson.Gson; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.log4j.Log4j2; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.OncePerRequestFilter; import org.zerock.apiserver.dto.MemberDTO; import org.zerock.apiserver.util.JWTUtil; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import java.util.Map; @Log4j2 public class JWTCheckFilter extends OncePerRequestFilter { @Override protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { //true == not check String path = request.getRequestURI(); log.info("------check uri---------"+path); if(path.startsWith("/api/member/")){ return true; } //false == check return false; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { log.info("----------------------"); log.info("----------------------"); log.info("----------------------"); String autoHeaderStr = request.getHeader("Authorization"); //bearer // 7개 후 JWT 문자열 try { String accessToken = autoHeaderStr.substring(7); Map<String, Object> claims = JWTUtil.validateToken(accessToken); log.info("JWT claims: " + claims); // filterChain.doFilter(request, response); String email = (String) claims.get("email"); String pw = (String) claims.get("pw"); String nickname = (String) claims.get("nickname"); Boolean social = (Boolean) claims.get("social"); List<String> roleNames = (List<String>) claims.get("roleNames"); MemberDTO memberDTO = new MemberDTO(email, pw, nickname, social.booleanValue(), roleNames); log.info("---------------------------------"); log.info(memberDTO); log.info(memberDTO.getAuthorities()); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(memberDTO, pw, memberDTO.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(authenticationToken); filterChain.doFilter(request, response); }catch(Exception e){ log.error("JWT Check Error --------------------"); log.error(e.getMessage()); Gson gson = new Gson(); String msg = gson.toJson(Map.of("error", "ERROR_ACCESS_TOKEN")); response.setContentType("application/json"); PrintWriter printWriter = response.getWriter(); printWriter.println(msg); printWriter.close(); } //destination filterChain.doFilter(request, response); } } 여기가 JWTCheckFilter부분입니다.
-
미해결Slack 클론 코딩[실시간 채팅 with React]
npm run dev 에러
npm run dev시 새로운 에러가 발생하여 재질문 드립니다.http://localhost:3090/Login 연결시, 크롬에서 Failed to compile. 가 발생하였습니다.Module not found: Can't resolve '@utils/fetcher' in '/Users/kanghyun/Desktop/study/react/zerocho/sleact/setting/front/layouts' layouts/workspace.tsx터미널 메세지입니다.ERROR in ./pages/Login/index.tsx 17:0-39Module not found: Error: Can't resolve '@hooks/useInput' in '/Users/kanghyun/Desktop/study/react/zerocho/sleact/setting/front/pages/Login'@ ./layouts/App.tsx 7:9-31@ ./client.tsx 9:0-32 12:95-98ERROR in ./pages/Login/index.tsx 19:0-37Module not found: Error: Can't resolve '@utils/fetcher' in '/Users/kanghyun/Desktop/study/react/zerocho/sleact/setting/front/pages/Login'@ ./layouts/App.tsx 7:9-31@ ./client.tsx 9:0-32 12:95-98ERROR in ./pages/SignUp/index.tsx 17:0-39Module not found: Error: Can't resolve '@hooks/useInput' in '/Users/kanghyun/Desktop/study/react/zerocho/sleact/setting/front/pages/SignUp'@ ./layouts/App.tsx 11:9-32@ ./client.tsx 9:0-32 12:95-98ERROR in ./pages/SignUp/index.tsx 23:0-37Module not found: Error: Can't resolve '@utils/fetcher' in '/Users/kanghyun/Desktop/study/react/zerocho/sleact/setting/front/pages/SignUp'@ ./layouts/App.tsx 11:9-32@ ./client.tsx 9:0-32 12:95-98 ㅡtsconfig.json 파일입니다"paths": { "@hooks/*": ["hooks/*"], "@components/*": ["components/*"], "@layouts/*": ["layouts/*"], "@pages/*": ["pages/*"], "@utils/*": ["utils/*"], "@typings/*": ["typings/*"] }ㅡwebpack.config.ts 파일입니다resolve: { extensions: ['.js', '.jsx', '.front', '.tsx', '.json'], alias: { '@hooks': path.resolve(__dirname, 'hooks'), '@components': path.resolve(__dirname, 'components'), '@layouts': path.resolve(__dirname, 'layouts'), '@pages': path.resolve(__dirname, 'pages'), '@utils': path.resolve(__dirname, 'utils'), '@typings': path.resolve(__dirname, 'typings'), // 경로 폴더들 }, },ㅡ현재 터미널 경로입니다/Desktop/study/react/zerocho/sleact/setting/frontts 폴더에서 설정 후, front 라는 폴더명으로 바꾸어서 진행중입니다. 감사합니다
-
해결됨(2025) MBTI 테스트 기반 수익형 웹사이트 만들기 - <코딩 배워 사업하자>
이용 약관 코드도 제공을 해 주시나요?
제공해주신 수업을 잘 들었습니다.마지막 수파베이스 강의에서 구글 Oauth와 연동할때 이용 약관 코드를 제공해 주신다는 언급이 있었던것 같은데, 어디에 올라가 있는지 여쭤보고 싶습니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
익스텐션 질문
안녕하세요 설치된 익스텐션이 궁금하여 질문드립니다.17:20에 return문에 h1태그를 추가하고 저장하시니까 ()가 자동으로 감싸지는데어떤 익스텐션을 설치해야하나요? 아니면 어떤 설정을 해야하나요?
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
7.1 서버 액션에서
import style from "./page.module.css"; // 변경 후: import Image from 'next/image'; import { notFound } from "next/navigation"; import { BookData } from "@/types"; export const dynamicParams = true; export async function generateStaticParams() { return [{id: "1"}, {id: "2"}, {id: "3"}]; } async function BookDetail({bookId}:{bookId:string}){ // params가 Promise이므로 먼저 await로 해결(resolve)해야 합니다 const response = await fetch(`${process.env.NEXT_PUBLIC_API_SERVER_URL}/book/${bookId}`) ; if (!response.ok){ if (response.status === 404) { notFound(); } return <section>Failed to fetch books</section>; } const book = await response.json(); const { id, title, subTitle, description, author, publisher, coverImgUrl } = book; return ( <section> <div className={style.cover_img_container} style={{ backgroundImage: `url('${coverImgUrl}')` }} > <img src={coverImgUrl} alt={title || "책 표지"} /> </div> <div className={style.title}>{title}</div> <div className={style.subTitle}>{subTitle}</div> <div className={style.author}> {author} | {publisher} </div> <div className={style.description}>{description}</div> </section> ); } function ReviewEditForm() { async function createReviewAction(formData: FormData) { "use server"; //console.log("server action called"); const content = formData.get("content")?.toString(); const author = formData.get("author")?.toString(); console.log("server action called", { content, author }); } return ( <section > <h2>리뷰 작성</h2> <form action={createReviewAction}> <textarea name="content" placeholder="리뷰를 작성해주세요" ></textarea> <input name="author" placeholder="작성자" /> <button type="submit">리뷰 작성</button> </form> </section> ); } export default function Page({ params }: { params: { id: string } }) { // const bookId = params.id; // 미리 params 처리 return ( <div className={style.container}> <BookDetail bookId={params.id}/> <ReviewEditForm/> </div> ) } 에서 Error: Route "/book/[id]" used `params.id`. `params` should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis at Page (src\app\book\[id]\page.tsx:79:33) 77 | return ( 78 | <div className={style.container}> > 79 | <BookDetail bookId={params.id}/> | ^ 80 | <ReviewEditForm/> 81 | </div> 82 | )이에러가 계속 나는데 chatgpt랑 계속 풀어 보려고 해도 쉽지 않네요 params 쓰는 시점 문제인거 같은데 강의 내용을 봐서는 잘모르겠네요 export default function Page({ params }: { params: { id: string } }) { // const bookId = params.id; // 미리 params 처리 return ( <div className={style.container}> <BookDetail bookId={params.id}/> <ReviewEditForm/> </div> ) }bookId 이 부분이 계속 async 어쩌구 하는데