묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
프로젝트 전체 다운 받아서 보려고 하는데 git 주소 알려주세요
프로젝트 전체 다운 받아서 보려고 하는데 git 주소 알려주세요
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
Section 50 결제처리 레벨업 추가 학습 주제
Section 50 결제처리 레벨업 추가 학습 주제에서 포인트 충전 관련하여 문의드립니다. createPointTransactionsOfLoading에 API를 요청 했는데 404에러가 나옵니다!아임포트(테스트용)로 결제 성공하였고 응답받은 impUid도 잘 추가하였고, accessToken도 헤더에 포함시켰습니다. 무슨 문제일까요?ㅠㅠ 요청 mutationmutation { createPointTransactionOfLoading(impUid: "imp_618843313239") { amount } }error메세지{ "errors": [ { "message": "Request failed with status code 404", "locations": [ { "line": 2, "column": 3 } ], "path": [ "createPointTransactionOfLoading" ], "extensions": { "code": "INTERNAL_SERVER_ERROR", "exception": { "stacktrace": [ "Error: Request failed with status code 404", " at Object.callErrorProcessor (/codecamp_backend_api/dist/common/libraries/errorProcessor.js:8:11)", " at CreatePointTransactionOfLoadingService.fetchPaymentFromImpUid (/codecamp_backend_api/dist/api/pointTransaction/services/mutation/createPointTransactionOfLoading.service.js:42:36)", " at runMicrotasks (<anonymous>)", " at processTicksAndRejections (internal/process/task_queues.js:93:5)", " at async target (/codecamp_backend_api/node_modules/@nestjs/core/helpers/external-context-creator.js:76:28)", " at async /codecamp_backend_api/node_modules/@nestjs/core/helpers/external-proxy.js:9:24" ] } } } ], "data": null
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
ant-design icons을 설치했음에도 StopOutlined 아이콘이 보이지 않습니다!(에러 메시지 없음)
안녕하세요! React로 NodeBird SNS 만들기섹션1 프로필 페이지 만들기까지 수강한 수강생입니다!제로초님 강의와 트위터 클론 깃허브를 확인해도 원인을 알 수 없어 질문 글 올립니다!항상 강의 잘 보고 있습니다! 제로초님 항상 감사합니다! 사전에 antd 4버전, ant-design icons 4버전을 설치하였습니다.import { StopOutlined } from '@ant-design/icons'; 위처럼 ant-design icons를 설치했지만 앤트 디자인 아이콘이 뜨지 않습니다.버전 문제라고 생각해 사이트에서 4버전의 StopOutlined 아이콘을 가져와다시 시도했으나 같은 결과가 나타났습니다.FollowList.jsFollowList 컴포넌트의 return 코드 중 의심되는 부분의 코드를 올립니다. renderItem={(item) => { <List.Item style={{ marginTop: 20 }}> <Card actions={[<StopOutlined key="stop" />]}> <Card.Meta description={item.nickname} /> </Card> </List.Item> }}
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
display: flex 의 기능은 무엇인가요?
프리캠프 css정렬강의에서자식 box들을 정렬하기 위하여, 부모 box의 속성 및 값으로 display: flex을 먼저 쓰고,flex-direction : row로 할건지, flex-direction : column으로 할건지 결정하고.이어 justify content나 align itmes등을 사용하던데그럼, display: flex의 기능은 무엇인가요?display : flex 라는 코드 없이 위의 flex기능들을 구사하면 문제가 생기나요??시험삼아 display : flex 라는 코드 없이 뒤이어flex-direction : row;justify items : center;align items : center; 라고 적고 확인해보니. 부모 박스 안에 자식 박스가 마치 flex-direction : column ; 만 실행된 것과 같은 효과가 나타났습니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
Get/user/followers API server error.
안녕하세요!강의를 어느정도 진행하고 프론트를 바꿔서 저만의 페이지를 구현하고 있습니다.구현하던 중 LOAD_FOLLOWERS_REQUEST 요청을 보내면 계속 500 에러가 뜹니다. 프론트의 saga, Redux action 만드는 부분 확인했고, 백엔드 쪽에 routes확인했는데, 특별한 이상한 점을 못찾았습니다.* Front- redux/user* Front-saga/user* Back-routes* console*redux error log. 어디 부분에서 에러가 나는것일까요?감사합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
Image Upload시 register 문의
안녕하세요.포트폴리오를 만들던 도중 제 스스로 해결되지 않아 질문드립니다.import { useForm } from "react-hook-form"; import { wrapFormAsync } from "../../../../../../commons/libraries/asyncFunc"; import { yupResolver } from "@hookform/resolvers/yup"; import { productRegisterSchema } from "../../../../../commons/validation/Main"; import InputLong from "../../../../../commons/Input/long"; import Textarea01 from "../../../../../commons/Input/textarea"; import Button01 from "../../../../../commons/button/01"; import InputLongNormal from "../../../../../commons/Input/longNormal"; import { gql, useMutation } from "@apollo/client"; import type { IMutation, IMutationCreateUseditemArgs, } from "../../../../../../commons/types/generated/types"; import { useRouter } from "next/router"; import ImageUpload01 from "../../../../../commons/imageUpload/imageUpload"; interface IFormData { name: string; remarks: string; contents: string; price: number; images: string[]; } export const CREATE_USED_ITEM = gql` mutation createUseditem($createUseditemInput: CreateUseditemInput!) { createUseditem(createUseditemInput: $createUseditemInput) { _id } } `; export default function ProductRegisterBody(): JSX.Element { const { register, handleSubmit, formState } = useForm<IFormData>({ resolver: yupResolver(productRegisterSchema), mode: "onChange", }); const router = useRouter(); const [createUseditem] = useMutation< Pick<IMutation, "createUseditem">, IMutationCreateUseditemArgs >(CREATE_USED_ITEM); const onClickSubmit = async (data: IFormData): Promise<void> => { console.log(data); await createUseditem({ variables: { createUseditemInput: { name: data.name, remarks: data.remarks, contents: data.contents, price: data.price, images: data.images, }, }, }); void router.push("/markets"); }; return ( <form onSubmit={wrapFormAsync(handleSubmit(onClickSubmit))}> <InputLong register={register("name")} tag="상품명" /> <div>{formState.errors.name?.message}</div> <InputLong register={register("remarks")} tag="한줄요약" /> <div>{formState.errors.remarks?.message}</div> <Textarea01 register={register("contents")} tag="상품설명" /> <div>{formState.errors.contents?.message}</div> <InputLong register={register("price")} tag="판매가격" /> <div>{formState.errors.price?.message}</div> <InputLongNormal tag="태그입력" /> <div>거래위치</div> <div> <p>사진첨부</p> <ImageUpload01 register={register("images")} /> </div> <button> 테스트</button> <Button01 title="등록하기" isActive={formState.isValid} onClick={onClickSubmit} /> </form> ); } import { useMutation } from "@apollo/client"; import { useState, type ChangeEvent, useRef } from "react"; import { UPLOAD_FILE } from "../upload01/Upload01.queries"; import type { IMutation, IMutationUploadFileArgs, } from "../../../commons/types/generated/types"; import * as S from "./styles"; import type { UseFormRegisterReturn } from "react-hook-form"; interface IInputProps { register: UseFormRegisterReturn; } export default function ImageUpload01(props: IInputProps): JSX.Element { const [image, setImage] = useState(""); const [images, SetImages] = useState(""); const fileRef = useRef<HTMLInputElement>(null); const [uploadFile] = useMutation< Pick<IMutation, "uploadFile">, IMutationUploadFileArgs >(UPLOAD_FILE); const onChangeImageFile = async ( event: ChangeEvent<HTMLInputElement>, ): Promise<void> => { const file = event.target.files?.[0]; const result = await uploadFile({ variables: { file } }); console.log(result.data?.uploadFile.url); SetImages(result?.data?.uploadFile?.url ?? ""); }; console.log(images); const onClickFile = (): void => { fileRef.current?.click(); }; return ( <> <S.Wrapper> <S.Image src={`https://storage.googleapis.com/${images}`} alt="" /> <S.ImageClick onClick={onClickFile}> +</S.ImageClick> <S.HiddenInput onChange={onChangeImageFile} type="file" ref={fileRef} /> <S.HiddenInput value={images} {...props.register} autoFocus name="images" /> </S.Wrapper> </> ); } 일단 요령이 없어서 아래 처럼 만들었습니다.사진을 올리면 register를 위해 value값이 변경되는 input창을 만들었으나 등록하기를 누르면 graphql에 업로드되지가 않습니다.{price: 333, contents: '3333', remarks: '333', name: '333', images: ''} 허나 저 빨간 v표시 친 부분을 한번 클릭한다면 {price: 33, contents: '3333', remarks: '333', name: '3333', images: 'codecamp-file-storage/2023/9/17/Vector.png'}다음처럼 images가 잘 입력됩니다. 클릭하지 않아도 자동으로 변경되면 images를 업로드 시킬 수 있는 방법이 있을까요? 아니면 참고할만한 다른 방법들이 있을까요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
렌더링 관련? 경고가 뜹니다
섹션6까지 끝낸 상태입니다기능에는 문제가 없는데웹사이트 첫 방문으로 로그아웃 상태로 프로필 페이지에 들어가면 아래와 같은 경고가 뜹니다.찾아보니 컴포넌트에서 setState나 dispatch를 useEffect나 이벤트 함수 없이 컴포넌트에서그냥? 실행해서 생기는 경고인 듯한데 제 코드에는 그런게 없어서 오리무중입니다. 이 경고가 왜 뜨는건지, 무시해도 되는지, 어떻게 해결해야하는지 몰라서 질문 남깁니다.(수정-배포버전에서는 안 뜹니다)(참고로 쓰로틀링을 5초로 설정해서 페이지 이동 시간이 5초 걸렸을때는 페이지 이동시 종종Cannot update a componet (`AppLayout`) ~~~ inside `Nodebird 와 같은 경고도 발생했습니다쓰로틀링을 없애니 발생하지 않네요)_app.jsximport PropTypes from 'prop-types'; import Head from 'next/head'; import { Provider } from 'react-redux'; import wrapper from '../store/configureStore'; const NodeBird = ({ Component, ...rest }) => { const { store, props } = wrapper.useWrappedStore(rest); return ( <Provider store={store}> <Head> <meta charSet="utf-8" /> <link rel="shortcut icon" href="favicon.ico" /> <title>NodeBird</title> </Head> <Component {...props.pageProps} /> </Provider> ); }; NodeBird.propTypes = { Component: PropTypes.elementType.isRequired, }; export default NodeBird;profile.jsximport Head from 'next/head'; import { useEffect, useState, useCallback } from 'react'; import { useSelector } from 'react-redux'; import Router from 'next/router'; import axios from 'axios'; import { END } from 'redux-saga'; import useSWR from 'swr'; import AppLayout from '../components/AppLayout'; import NicknameEditForm from '../components/NicknameEditForm'; import FollowList from '../components/FollowList'; import { LOAD_MY_INFO_REQUEST } from '../reducers/user'; import wrapper from '../store/configureStore'; import { backUrl } from '../config/config'; const fetcher = (url) => axios.get(url, { withCredentials: true }).then((result) => result.data); const Profile = () => { const { me } = useSelector((state) => state.user); const [followersLimit, setFollowersLimit] = useState(3); const [followingsLimit, setFollowingsLimit] = useState(3); const { data: followersData, error: followerError } = useSWR(`${backUrl}/user/followers?limit=${followersLimit}`, fetcher); const { data: followingsData, error: followingError } = useSWR(`${backUrl}/user/followings?limit=${followingsLimit}`, fetcher); useEffect(() => { if (!me?.id) { // 로그아웃했을때 Router.replace('/'); } }, [me?.id]); const loadMoreFollowers = useCallback(() => { setFollowersLimit((prev) => prev + 3); }, []); const loadMoreFollowings = useCallback(() => { setFollowingsLimit((prev) => prev + 3); }, []); if (!me) { return null; } if (followerError || followingError) { console.error(followerError || followingError); return <div>팔로잉/팔로워 로딩 중 에러가 발생합니다</div>; } return ( <> <Head> <title>내 프로필 | NodeBird</title> </Head> <AppLayout> <NicknameEditForm /> <FollowList header="팔로잉" data={followingsData} onClickMore={loadMoreFollowings} loading={!followingsData && !followingError} /> <FollowList header="팔로워" data={followersData} onClickMore={loadMoreFollowers} loading={!followersData && !followerError} /> </AppLayout> </> ); }; export const getServerSideProps = wrapper.getServerSideProps((store) => async ({ req }) => { axios.defaults.headers.Cookie = req?.headers.cookie; store.dispatch({ type: LOAD_MY_INFO_REQUEST, }); store.dispatch(END); await store.sagaTask.toPromise(); }); export default Profile;
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
피그마 CSS 속성이 안보여요
강의에서처럼 이미지를 클릭해도오른쪽 하단에 css 정보가 안보여요..
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
폐쇄망에서 package 추가
구글링을 해서 폐쇄망에 react 프로젝트를 어찌어찌 설치를 했습니다.정상적으로 실행도 되고 프로그래밍도 가능합니다.근데, 중간에 패키지를 추가하려고 인터넷이 가능한 곳에서 패키지를 추가해서옮겨보려 했으나 잘 안되더군요.폐쇄망에서 패키지 추가는 어떻게 해야 하는지 도움 부탁드립니다.
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
게시글 등록,삭제시 실시간 반영되지 않습니다.
안녕하세요 제로초님 강의듣고 리덕스, 사가 대신 툴킷과 내장 썽크를 사용해서 다시 만들어보는 중인데 게시글 등록시 글은 정상적으로 등록이 되는데 게시글 갯수가 실시간으로 바뀌지 않고 새로고침 해야 반영이 됩니다. 삭제할때도 정상적으로 삭제는 되는데 새로고침해야 삭제된 결과가 반영이 됩니다. 백엔드 부분은 강의와 같이 js로 작성했고 게시글 작성 툴킷은 다음과 같이 코드작성했습니다. // toolkit/post.ts export const initialState: PostState = { // 기본값 mainPosts: [], imagePaths: [], postAdded: false, // 게시글 로딩 loadPostLoading: false, loadPostDone: false, loadPostError: null, // 추가 로딩 hasMorePosts: false, // 게시글 작성 addPostLoading: false, addPostDone: false, addPostError: null, // 게시글 삭제 removePostLoading: false, removePostDone: false, removePostError: null, export const addPostAction = createAsyncThunk( 'post/addPost', async (data: FormData) => { const response = await axios.post('/post', data); return response.data; } ); export const removePostAction = createAsyncThunk( '/post/delete', async (data: number) => { const response = await axios.delete(`/post/${data}`); return response.data; } ); extraReducers: (builder) => { builder // 게시글 추가 .addCase(addPostAction.pending, (draft) => { draft.addPostLoading = true; draft.addPostDone = false; draft.addPostError = null; }) .addCase(addPostAction.fulfilled, (draft, action) => { draft.addPostLoading = false; draft.addPostDone = true; draft.mainPosts.unshift(action.payload); }) .addCase(addPostAction.rejected, (draft, action) => { draft.addPostLoading = false; draft.addPostError = action.error.message; }) // 게시글 삭제 .addCase(removePostAction.pending, (draft) => { draft.removePostLoading = true; draft.removePostDone = false; draft.removePostError = null; }) .addCase(removePostAction.fulfilled, (draft, action) => { draft.removePostLoading = false; draft.removePostDone = true; draft.mainPosts = draft.mainPosts.filter( (v) => v.id !== action.payload ); }) .addCase(removePostAction.rejected, (draft, action) => { draft.removePostLoading = false; draft.removePostError = action.error.message; }) 이해가 안가는 부분이 post에서 게시글 삭제, 입력등의 작업을 하고 user에서 회원가입,로그인,로그아웃, 팔로우 등의 작업을 하게 나눠놨는데 게시글 입력할때 mainPosts의 값이 추가될때마다 그 값이 컴포넌트에서 불러와져서 화면의 게시글 갯수 부분이 바뀌는건 이해가 가는데 // pages/index.ts const Home = () => { const { mainPosts, hasMorePosts, loadPostLoading } = useSelector( (state: RootState) => state.post ); {me && <PostForm />} {mainPosts.map((post) => ( <PostCard key={post.id} post={post} /> ))} 이 부분에서/component/UserProfile.tsx const UserProfile = () => { const { me, logOutLoading } = useSelector((state: RootState) => state.user); return ( <> <Card actions={[ <div key='twit'> 짹짹 <br /> {me?.Posts.length} </div>, <div key='follower'> 팔로워 <br /> {me?.Followings.length} </div>, <div key='following'> 팔로잉 <br /> {me?.Followers.length} </div>, ]} > me는 툴킷의 user.ts 의 me를 참조하는거 아닌가요? 게시글 입력,삭제시 post.ts를 통해 post.ts의 mainPosts 값이 바뀌는데 user.ts를 참조하는 컴포넌트에서 me.Posts.length 값이 바뀌는 부분이 잘 이해가 가질 않습니다. 그리고 댓글 삭제기능을 추가하고 싶은데요. //pages/index.ts const { mainPosts, hasMorePosts, loadPostLoading } = useSelector( (state: RootState) => state.post ); {mainPosts.map((post) => ( <PostCard key={post.id} post={post} /> ))} //component/PostCard.tsx const { removePostLoading } = useSelector((state: RootState) => state.post); const onRemovePost = useCallback(() => { dispatch(removePostAction(post.id)); }, []); // post.ts export const removePostAction = createAsyncThunk( '/post/delete', async (data: number) => { const response = await axios.delete(`/post/${data}`); return response.data; } ); .addCase(removePostAction.fulfilled, (draft, action) => { draft.removePostLoading = false; draft.removePostDone = true; draft.mainPosts = draft.mainPosts.filter( (v) => v.id !== action.payload ); }) //back/routes/post router.delete('/:postId', isLoggedIn, async (req, res, next) => { try { await Post.destroy({ where: { id: req.params.postId, UserId: req.user.id }, }); res.status(200).json({ PostId: parseInt(req.params.postId, 10) }); } catch (err) { console.error(err); next(err); } }); 게시글을 삭제할때는 post.id로 해당하는 글의 id를 바로 보내서 삭제할수 있는건 이해가 가는데 comment의 경우 [{댓글1}, {댓글2}] 형식으로 각 댓글의 값이 들어있어서 이부분을 어떻게 해야할지 감이 잡히지 않습니다.
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
Incorrect use of <label for=FORM_ELEMENT> 오류 발생했을 때 Input에 name이 아닌 id 값을 주면 해결되는 이유가 궁금합니다!
안녕하세요! React로 NodeBird SNS 만들기섹션1 로그인 폼 만들기까지 수강한 학생입니다!사전에 next 9버전, antd 4버전을 설치하였습니다.import { Form, Input, Button } from 'antd';발생한 에러는 아래와 같습니다.콘솔에 오류가 뜨지만 화면 자체는 정상적으로 뜹니다.에러 메시지를 번역해보니 아래와 같았습니다.(오류 추정 코드이며, 버튼 코드는 아래에선 생략했습니다.)return ( <Form> <div> <label htmlFor="user-id">아이디</label> <br /> <Input name="user-id" value={id} onChange={onChangeId} required /> </div> <div> <label htmlFor="user-password">비밀번호</label> <br /> <Input name="user-password" type="password" value={password} onChange={onChangePassword} required /> </div> </Form> );에러 메시지를 확인하고 문제가 LoginForm.js 파일에서 발생한 것이라 추측했고,LoginForm의 return에 있는 Input name 속성을 id로 변경하니 콘솔 오류가 사라졌습니다.왜 해결된 것인지 이유가 궁금합니다!return ( <Form> <div> <label htmlFor="user-id">아이디</label> <br /> <Input id="user-id" value={id} onChange={onChangeId} required /> </div> <div> <label htmlFor="user-password">비밀번호</label> <br /> <Input id="user-password" type="password" value={password} onChange={onChangePassword} required /> </div> </Form> );
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
accessToken 저장 관련 질문
안녕하세요! accessToken 저장 관련하여 궁금한 점이 생겨 질문드립니다.로그인의 결과로 accessToken을 받아오고 이것을 보안 문제를 해결하고자 로컬/세션 스토리지가 아닌 변수(recoil state)에 저장하셨고 이를 로그인한 사람의 정보를 요청하기 위해 쿠키를 통해 headers에 연동 시키셨는데, 이러면 변수에 저장한 값을 어쨌든 headers의 쿠키에서 확인할 수 있게 되어 글로벌 변수에 저장한 의미가 없어진 것 아닐까 하는 생각이 들어서 질문드리게 되었습니다.항상 좋은 강의 감사드립니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
회원가입과제
안녕하세요. 회원가입 과제를 하려고 하는데너무 막막해서요...모양만 똑같이 만들면 되는 건가요?아니면 실제로 입력이 되는 형식대로 만들어야 하는 건가요?
-
해결됨따라하며 배우는 리액트 A-Z[19버전 반영]
NestJS 13에서의 컴포넌트 관리
안녕하세요! NextJS 13 강의를 듣는 과정에서 궁금증이 생겨 질문 드립니다.기존의 React 같은 경우에는 컴포넌트에 path를 지정하여 라우팅하는 방식으로 코드를 작성해나갔었던 것 같은데요,NextJS의 경우 about 페이지를 만들기 위해 about.tsx를 작성함으로써 라우팅을 구현하고, NextJS 13의 경우 디렉토리를 path 구조로 작성하여 라우팅을 구현하는 것으로 이해했습니다.React에서는 컴포넌트에 일일이 라우팅 path를 정해주기 때문에, 재사용 가능한 컴포넌트로 독립적으로 사용할 수 있었던 것 같은데 NextJS의 경우 재사용 컴포넌트를 어떻게 관리하는지 궁금하여 질문 드립니다.또한 리액트 version 18에서 Suspense를 통한 서버사이드렌더링이 SEO에 영향을 미치는지, 혹시나 SEO를 개선할 수 있다면 NextJS를 사용하지 않고 React 만으로 최적화된 앱을 만들 수 있는지 추가적으로 질문 드립니다.좋은 강의 덕에 열심히 듣고 있습니다. 질문 읽어주셔서 감사합니다!
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
섹션 36 antd icon 임포트 에러
안녕하세요.antd 임포트할때 이런 에러가 발생했는데요.이전 커뮤니티 글을 확인해서선생님이 말씀해주신 강의용 버전으로 바꾸고yarn.lock과 노드모듈즈를 다시 지운다음yarn install했는데도 아직도 저렇게 에러가 나와서요ㅠㅠ뭐가 문제일까요?yarn dev해보니 아이콘은 잘 나와요
-
해결됨Next.js 시작하기(feat. 지도 서비스 개발)
a tag 질문 !
안녕하세요 !강의 중에 a tag를 감싸고 있는 컴포넌트를 만들경우라고 하셨는데 useRouter나 Link를 쓰게 되면 a tag를 굳이 안써도 되지 않을까 생각하는데 그럼에도 불구하고 a tag를 쓰는 경우가 있을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
린터와 포맷터 강의 중 inport부분 파싱 에러
강사님 설치하는것도 잘 따라했는데강사님은 import부분에 오류가 안뜨는데 저는 import부분에서 이런 오류가 뜨더라고요. tsconfig에서 뭐가 잘못됐단건지 모르겠어요ㅠ
-
해결됨Next.js 시작하기(feat. 지도 서비스 개발)
8분 20초 배포 관련
안녕하세요!마지막에 8:20에 나오는 설명대로 commit을 나누어서 진행하고 push and build를 하였는데 아래와 같이 error가 발생하고 있습니다. 어떤 부분이 문제인지 궁금합니다Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error SyntaxError: Unexpected token < in JSON at position 0 Error: Export encountered errors on following paths:/ 아래에 코드로 build하면 정상적으로 동작합니다..const stores = (await import('../public/stores.json')).default
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
Immer 적용시 에러 문의드립니다.
안녕하세요. React Immer 적용시 나타나는 에러인데확인한번 부탁드려도 될까요?Immer 적용 전까지 코드는 잘 돌아갔는데, 에러 추적이 힘드네요. 웹 팩 환경설정 문제일까요? immer module은 잘 설치되어 있습니다. 에러내용소스코드front/reducers/user.jsimport produce from 'immer'; export const initialState = { logInLoading : false, // 로그인 시도중 logInDone : false, loginError : null, logOutLoading : false, // 로그아웃 시도중 logOutDone : false, logOutError : null, signUpLoading : false, // 회원가입 시도중 signUpDone : false, signUpFailure : null, changeNicknameLoading : false, // 닉네임 변경 시도중 changeNicknameDone : false, changeNicknameFailure : null, me : null, signUpData : {}, loginData : {}, }; const dummyUser = (data) => ({ ...data, nickname : '제로초', id : 1, Posts : [{ id : 1}], Followings : [{nickname : 'AAA'}, {nickname : 'BBB'}, {nickname : 'CCC'}], Followers : [{nickname : 'AAA'}, {nickname : 'BBB'}, {nickname : 'CCC'}], }); export const LOG_IN_REQUEST = 'LOG_IN_REQUEST'; // 액션의 이름 export const LOG_IN_SUCCESS = 'LOG_IN_SUCCESS'; export const LOG_IN_FAILURE = 'LOG_IN_FAILURE'; export const LOG_OUT_REQUEST = 'LOG_OUT_REQUEST'; // 액션의 이름 export const LOG_OUT_SUCCESS = 'LOG_OUT_SUCCESS'; export const LOG_OUT_FAILURE = 'LOG_OUT_FAILURE'; export const SIGN_UP_REQUEST = 'SIGN_UP_REQUEST'; export const SIGN_UP_SUCCESS = 'SIGN_UP_SUCCESS'; export const SIGN_UP_FAILURE = 'SIGN_UP_FAILURE'; export const CHANGE_NICKNAME_REQUEST = 'CHANGE_NICKNAME_REQUEST'; export const CHANGE_NICKNAME_SUCCESS = 'CHANGE_NICKNAME_SUCCESS'; export const CHANGE_NICKNAME_FAILURE = 'CHANGE_NICKNAME_FAILURE'; export const FOLLOW_REQUEST = 'FOLLOW_REQUEST'; export const FOLLOW_SUCCESS = 'FOLLOW_SUCCESS'; export const FOLLOW_FAILURE = 'FOLLOW_FAILURE'; export const UNFOLLOW_REQUEST = 'UNFOLLOW_REQUEST'; export const UNFOLLOW_SUCCESS = 'UNFOLLOW_SUCCESS'; export const UNFOLLOW_FAILURE = 'UNFOLLOW_FAILURE'; export const ADD_POST_TO_ME = 'ADD_POST_TO_ME'; export const REMOVE_POST_OF_ME = 'REMOVE_POST_OF_ME'; export const signUpAction = (data) => { return { type: SIGN_UP_REQUEST, data, }; }; export const changeNicknameAction = (data) => { return { type: CHANGE_NICKNAME_REQUEST, data, }; }; export const loginRequestAction = (data) => { return { type: LOG_IN_REQUEST, data, } }; export const logoutRequestAction = { type: LOG_OUT_REQUEST, }; const reducer = (state = initialState, action) => produce(state, (draft) => { switch (action.type) { // 로그인 case LOG_IN_REQUEST: draft.state = true; draft.loginError = null; draft.logInDone = false; break; case LOG_IN_SUCCESS: draft.logInLoading = false; draft.logInDone = true; draft.me = dummyUser(action.data); break; case LOG_IN_FAILURE: draft.logInLoading = false; draft.loginError = action.error; break; // 로그아웃 case LOG_OUT_REQUEST : draft.logOutLoading = true; draft.logOutError = null; break; case LOG_OUT_SUCCESS : draft.logOutLoading = false; draft.logOutDone = false; draft.me = null; break; case LOG_OUT_FAILURE : draft.logOutLoading = false; draft.logOutError = action.error; break; // 회원가입 case SIGN_UP_REQUEST : draft.signUpLoading = true; draft.signUpDone = false; draft.signUpError = null; break; case SIGN_UP_SUCCESS : draft.signUpLoading = false; draft.signUpDone = true; break; case SIGN_UP_FAILURE : draft.signUpLoading = false; draft.signUpData = action.error; break; // 닉네임 변경 case CHANGE_NICKNAME_REQUEST : draft.changeNicknameLoading= true; draft.changeNicknameDone= false; draft.changeNicknameError= null; break; case CHANGE_NICKNAME_SUCCESS : draft.changeNicknameLoading = false; draft.changeNicknameDone = true; break; case CHANGE_NICKNAME_FAILURE : draft.changeNicknameLoading = false; draft.changeNicknameData = action.error; break; // 게시글 등록시 사용자 dummy Data에 동기화 case ADD_POST_TO_ME : draft.me.Posts.unshift({ id : action.data}) break; // return { // ...state, // me : { // ...state.me // Posts: [ { id.action.data}, ...state.me.Posts] // } // } // 게시글 삭제 case REMOVE_POST_OF_ME : draft.me.Posts = draft.me.Posts.filter((v) => v.id !== action.data) break; // return { // ...state, // me : { // ...state.me, // Posts : state.me.Posts.filter((v) => v.id !== action.data) // } // } default: break; } }); export default reducer;
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
section 28 과제 중 오류
TypeError: Cannot read properties of undefined (reading 'target') 이런 오류를 어떻게 해결해야 할 지 모르겠습니다!