173만명의 커뮤니티!! 함께 토론해봐요.
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
회원가입이나 로그인 후 주소가 http://localhost:3000/login ? 이나 http://localhost:3000/signUp ? 으로 이동해지며, url 뒤에 물음표가 붙습니다. 가끔 Failed to fetch 메시지가 뜨는것은 너무 많이 요청을 보내서 그런것같습니다만, 그것과 무관하게 아래의 이슈가 사라지지 않습니다. 지금 학습단계에서 임시로 사용하기로한 로컬스토리지때문에 발생한 이슈일까요? import React, { useEffect } from 'react'; import { ApolloLink, ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'; import { createUploadLink } from 'apollo-upload-client' import { useRecoilState } from 'recoil'; import { accessTokenState } from '@/src/commons/store'; interface Props { children: JSX.Element; } const GLOBAL_STATE = new InMemoryCache() const ApolloSetting = (props: Props) => { const [accessToken, setAccessToken] = useRecoilState(accessTokenState) useEffect(() => { if (localStorage.getItem("accessToken")) { setAccessToken(localStorage.getItem("accessToken") ?? "") } }, []) const uplodLink = createUploadLink({ uri: "http://backendonline.codebootcamp.co.kr/graphql", headers: { Authorization: `Bearer ${accessToken}` } }) const client = new ApolloClient({ link: ApolloLink.from([uplodLink as unknown as ApolloLink]), cache: GLOBAL_STATE }); return <ApolloProvider client={client}>{props.children}</ApolloProvider>; }; export default ApolloSetting; import { Title } from '@/src/commons/styles/emotion' import * as S from './Login_styles' import React, { useEffect, useState } from 'react' import { useMutation } from '@apollo/client' import { type IMutation, type IMutationLoginUserArgs } from '@/src/commons/types/generated/types' import { LOGIN_USER } from './Login_query' import { Modal } from 'antd' import { useRouter } from 'next/router' import { useRecoilState } from 'recoil' import { accessTokenState } from '@/src/commons/store' const Login_presenter = () => { const [accessToken, setAccessToken] = useRecoilState(accessTokenState) const router = useRouter() const [input, setInput] = useState({ email: '', password: '', }) const onChangeInput = (e: React.ChangeEvent<HTMLInputElement>) => { setInput({ ...input, [e.currentTarget.id]: e.currentTarget.value }) } const [loginUser] = useMutation<Pick<IMutation, 'loginUser'>, IMutationLoginUserArgs>(LOGIN_USER); const onSubmitSignUp = async () => { if (!input.email.includes("@") || !input.email.includes(".")) { Modal.error({ content: "이메일이 유효하지 않습니다." }); return } if (input.email && input.password) { try { const result = await loginUser({ variables: { email: input.email, password: input.password } }); if (!result.data) { Modal.error({ content: "로그인에 실패하였습니다." }); return } const accessToken = result.data?.loginUser.accessToken if (setAccessToken) { setAccessToken(accessToken || "") // 3. 로그인 성공페이지로 이동하기 void router.push('/') localStorage.setItem("accessToken", accessToken) // 임시로 사용 나중에 지울예정 } } catch (error) { if (error instanceof Error) { alert(error.message) } } } } return ( <S.LoginForm> <Title style={{ color: '#fff', "textAlign": "center", "marginBottom": "20px" }}>로그인</Title> <S.InputContainer> <S.Label htmlFor='email'>이메일</S.Label> <S.Input id='email' placeholder='이메일을 입력해주세요.' onChange={onChangeInput} /> </S.InputContainer> <S.InputContainer> <S.Label htmlFor='password'>비밀번호</S.Label> <S.Input id='password' placeholder='비밀번호를 입력해주세요.' onChange={onChangeInput} autoComplete="on" type='password' /> </S.InputContainer> <S.SubmitButton onClick={onSubmitSignUp}>로그인</S.SubmitButton> </S.LoginForm> ) } export default Login_presenter import { accessTokenState } from '@/src/commons/store'; import { type IQuery } from '@/src/commons/types/generated/types'; import { gql, useQuery } from '@apollo/client'; import * as S from './Header_style' import { useRouter } from 'next/router'; import { useRecoilState } from 'recoil'; import { useEffect, useState } from 'react'; const FETCH_USER_LOGGED_IN = gql` query fetchUserLoggedIn { fetchUserLoggedIn{_id picture email name} } `; const Header = () => { const [accessToken] = useRecoilState(accessTokenState) const [isMounted, setIsMounted] = useState(false) const router = useRouter(); useEffect(() => { setIsMounted(true) }, []) const { data } = useQuery<Pick<IQuery, 'fetchUserLoggedIn'>>(FETCH_USER_LOGGED_IN); const onClickLogout = () => { if (localStorage) { localStorage.removeItem("accessToken") router.reload() } } return ( <S.Header> <S.Logo onClick={async () => await router.push(`/boards`)}> 🚢 FREE BOARD </S.Logo> {isMounted && <S.HeaderButtons> {!accessToken && <S.Login onClick={() => { void router.push(`/login`) }}>로그인</S.Login>} {!accessToken && <S.Signup onClick={async () => await router.push(`/signUp`)}>회원가입</S.Signup>} {accessToken && <S.Login onClick={onClickLogout}>로그아웃</S.Login>} {accessToken && <div>{data?.fetchUserLoggedIn.name}</div>} {accessToken && <div>{data?.fetchUserLoggedIn.email}</div>} {data?.fetchUserLoggedIn.picture && <img src={data?.fetchUserLoggedIn.picture}></img>} </S.HeaderButtons>} </S.Header> ); }; export default Header;
seo node.js nodejs graphql react next.js Next.js
이경석
2023-02-14T08:28:49.835Z
댓글 1
좋아요 0
조회수 3720
미해결
따라하며 배우는 리액트 A-Z[19버전 반영]
안녕하세요 따라하며 배우는 리액트 A-Z 섹션2 6번째 강의를 수강하던 중 button 태그에 스타일을 줄 때 float가 undefined 된다는 오류가 잘 해결 되지 않아 방법을 여쭙니다.
Next.js tdd redux react next.js typescript
dongbb00
2023-02-14T07:25:09.609Z
댓글 1
좋아요 0
조회수 783
미해결
[리뉴얼] React로 NodeBird SNS 만들기
PostHashtag(Post와 Hashtag 중간 테이블)에서 findAll을 해서 hashtag이름 까지 가지고 오는 방법이 있을 까요? 지금은 해쉬태그 Id까지밖에 가지고 오지 못해서요
redux react node.js express nodejs next.js Next.js
bs44108
2023-02-14T06:54:04.656Z
댓글 1
좋아요 0
조회수 351
해결됨
Next.js 시작하기(feat. 지도 서비스 개발)
vs code로 작업해도 상관없을까요? 그리고 npm 말고 yarn을 사용하시는 이유가 궁금합니다.
next.js seo Next.js vercel vercel csr csr ssg ssr ssg
누리
2023-02-14T03:10:34.875Z
댓글 1
좋아요 2
조회수 638
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
해당강의 찾아봐도 셋팅하는 부분은 안나오고 그냥 설치시 버전 오류가 발생합니다.
seo node.js react nodejs next.js graphql Next.js
Kwangsic Hyun
2023-02-13T12:08:52.413Z
댓글 1
좋아요 0
조회수 386
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
위의 사진은 section2 quiz입니다. section별 quiz 정답을 못찾겟네요!! 고난도는 답이 따로 없다고는 기억 하고있는데 고난도를 제외한 문제들의 정답들은 어디있나요? ㅎㅎ
node.js Next.js react nodejs next.js seo graphql
임프런
2023-02-13T08:08:57.338Z
댓글 1
좋아요 0
조회수 313
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
boardCommentWrite.container 댓글 작성 컨테이너 안에서 작동된 업데이트 함수의 refetchQueries 가 어떻게 다른 폴더의 boardCommentList.presenter 댓글 리스트 프리젠터 부분을 정확히 리페치 시켜주는지 원리를 잘 모르겠습니다. isEdit = true, false 같은 경우에는 댓글 수정화면 또는 리스트 화면으로 변경되는건 setIsEdit 함수를 자식 컴포넌트에 props drilling 했기에 바꿔줄 수 있다는 부분은 이해가 됐습니다. 그런데 아무리 부모 자식 관계라도 아예 다른 경로에 존재하고 뭔가 setIsEdit 같은 직접적인 매개체도 없는데 어떻게 부모 컴포넌트의 댓글 리스트의 존재와 위치를 알고 그 부분을 정확히 refetchQueries 를 시켜준건지 원리가 궁금합니다.
node.js Next.js nodejs react next.js seo graphql
FRONTEER
2023-02-12T09:40:08.770Z
댓글 1
좋아요 0
조회수 479
미해결
따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
client 쪽에서는 에러가 안나지만 server 쪽에서 데이터는 잘 받지만 Error: DataSource is not set for this entity. 나네요. 백엔드쪽은 익숙하지가 않아 구글링을 해봐도 어디서 에러가 나는지 잘 모르겠습니다. 게시판에 유사한 글이 있긴 하지만 해결책을 안되어 문의 드려요. AppDataSource는 이렇게 되어있습니다. 제 깃 주소는 https://github.com/ssinking91/Reddit 입니다. 이 버그 너무 해결하고 싶습니다. 감사합니다. 임시방편으로 모든 entity를 불러와 AppDataSource의 entities경로로 넣어 줬습니다. 혹시 에러나시는 분들 임시방편으로 이렇게 해주시면 잘 됩니다. import "reflect-metadata"; import { DataSource } from "typeorm"; import User from "./entities/User"; import Post from "./entities/Post"; import Sub from "./entities/Sub"; import Comment from "./entities/Comment"; import Vote from "./entities/Vote"; export const AppDataSource = new DataSource({ type: "postgres", host: "localhost", port: 5432, username: "postgres", password: "password", database: "postgres", synchronize: true, logging: false, // entities: ["src/entities/**/*.ts"], entities: [User, Post, Sub, Comment, Vote], migrations: [], subscribers: [], });
node.js Next.js 클론코딩 docker typescript 클론코딩 react nodejs next.js postgresql
tlsgkdals71
2023-02-12T08:21:52.215Z
댓글 1
좋아요 2
조회수 1067
해결됨
[리뉴얼] React로 NodeBird SNS 만들기
Redux Toolkit을 써보고 싶은데 고민이 생겼습니다. 제로초 님이 실무에서 리덕스 할 떄 Saga를 더 잘 쓰셨다고 말씀하셨던 거 같습니다. 근데 Redux Toolkit을 쓰려면 Thunk를 쓰는 게 더 편할 거 같은데 어떻게 생각하시나요?? 그리고 이미 Saga를 열심히 배워놨고 익숙해 졌는데 Toolkit를 쓰려고 Thunk로 다시 돌아가야 된다는 게 조금 배웠던 시간이 아깝기도 하고 고민중입니다. 물론 둘 다 동일한 비동기 요청을 하는 기능을 하는 것이지만 배우고 있는 입장에서는 고민이네요. 제로초 님은 Redux Toolkit 쓸 때에도 Saga를 같이 쓰시는 편인가요? +인피니트 스크롤링을 구현할때의 경우도 생각을 해봐야 될 거 같은데, 이부분은 강의를 끝까지 안 들어봐서 어떤 결정이 나을지 모르겠네요
express react node.js redux nodejs next.js Next.js
신영 유
2023-02-12T05:23:44.105Z
댓글 2
좋아요 0
조회수 506
미해결
[리뉴얼] React로 NodeBird SNS 만들기
리듀서에서 draft사용은 기본 state 이고 action은 dispatch에 받아온 값인거죠?
express react node.js redux nodejs next.js Next.js
오일중
2023-02-12T01:40:34.506Z
댓글 1
좋아요 0
조회수 332
미해결
만들면서 배우는 프론트엔드 DO IT 코딩 (Next.js, Typescript)
강사님 안녕하세요:) 구글 계정 로그인을 구현하다가 제목과 같은 에러가 발생했습니다(구글로그인 버튼 클릭시). 팝업을 열기 위한 url이 잘못되었다고 나오는데 어느 부분이 잘못되었는지 감이 안잡히네요ㅠ .env에 있는 내용을 next.config.js에서 export했고 FirebaseClient에서 FirebaseCredentials로 잘 매칭한 것 같은데 이상하네요.. 어떻게 접근하면 좋을까요.??
SJ Kim
2023-02-11T04:07:23.983Z
댓글 1
좋아요 0
조회수 777
해결됨
따라하며 배우는 리액트 A-Z[19버전 반영]
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 위는 JSX고 아래는 자바스크립트라서 묶어주는 괄호가 다른건가요?? 똑같이 소괄호 또는 중괄호 하면 오류가나는데 이유가 있나요??
Next.js redux typescript next.js tdd react
oridori2705
2023-02-10T14:04:53.528Z
댓글 1
좋아요 0
조회수 2279
해결됨
따라하며 배우는 리액트 A-Z[19버전 반영]
안녕하세요 수업에서 보여주는 nextjs13 관련 pdf 문서는 따로 공유 안 되는 걸까요...?
typescript tdd react next.js redux Next.js
이은혜
2023-02-10T13:33:45.502Z
댓글 1
좋아요 2
조회수 505
미해결
[리뉴얼] React로 NodeBird SNS 만들기
다이나믹 라우팅을 할때 next-redux-wrapper 7버전 이상 사용하고 있는데 질문이 2가지가 있습니다! 구동방식에 대해서는 이해했는데 getServerSideProps 에 loadPost에 context.params.id 가 아니라 7버전 이상이여서 req.params.id로 넣어줬는데 백엔드에서 받는 postId가 undefined로 뜹니다 혹시 7버전이상일땐 loadPost에는 어떤 값을 넣어줘야하나요..!? 게시글에 <Link>를 사용해서 다이나믹 라우터를 이용하면 처음에 CSR 방식으로 값을 받아와서 데이터가 없기 때문에 undefined가 뜨기 때문에 그 동안 로딩창을 띄워줘야 된다고 말씀하셨는데 그 말씀 자체에는 이해가 됐는데 그러면 getServerSideProps 에 따로 작업을 해줘야하는건가요!?
express react node.js nodejs redux next.js Next.js
CJW
2023-02-10T10:46:33.233Z
댓글 1
좋아요 0
조회수 345
미해결
[리뉴얼] React로 NodeBird SNS 만들기
PostImages.js import React, { useCallback, useState } from 'react'; import PropTypes from 'prop-types'; import { PlusOutlined } from '@ant-design/icons'; import ImagesZoom from './ImagesZoom'; const PostImages = ({ images }) => { const [showImagesZoom, setShowImagesZoom] = useState(false); const onZoom = useCallback(() => { setShowImagesZoom(true); }, []); const onClose = useCallback(() => { setShowImagesZoom(false); }, []); if (images.length === 1) { return ( <> <img role="presentation" src={images[0].src} alt={images[0].src} onClick={onZoom} /> {showImagesZoom && <ImagesZoom images={images} onClose={onClose} />} </> ); } if (images.length === 2) { return ( <> <div> <img role="presentation" src={images[0].src} alt={images[0].src} width="50%" onClick={onZoom} /> <img role="presentation" src={images[1].src} alt={images[1].src} width="50%" onClick={onZoom} /> </div> {showImagesZoom && <ImagesZoom images={images} onClose={onClose} />} </> ); } return ( <> <div> <img role="presentation" src={images[0].src} alt={images[0].src} width="50%" onClick={onZoom} /> <div role="presentation" style={{ display: 'inline-block', width: '50%', textAlign: 'center', verticalAlign: 'middle' }} onClick={onZoom} > <PlusOutlined /> <br /> {images.length - 1} 개의 사진 더보기 </div> </div> {showImagesZoom && <ImagesZoom images={images} onClose={onClose} />} </> ); }; PostImages.propTypes = { images: PropTypes.arrayOf(PropTypes.shape({ src: PropTypes.string, })).isRequired, }; export default PostImages; Post.js export const initialState = { mainPosts: [{ id: 1, User: { id: 1, nickname: '제로초', }, content: '첫 번째 게시글', Images: [{ src: 'https://bookthumb-phinf.pstatic.net/cover/137/995/13799585.jpg?udate=20180726', }, { src: 'https://gimg.gilbut.co.kr/book/BN001958/rn_view_BN001958.jpg', }, { src: 'https://gimg.gilbut.co.kr/book/BN001998/rn_view_BN001998.jpg', }], Comments: [{ User: { nickname: 'nero', }, content: '우와 개정판이 나왔군요~', }, { User: { nickname: 'hero', }, content: '얼른 사고싶어요~', }] }], imagePaths: [], postAdded: false, }; const ADD_POST = 'ADD_POST'; export const addPost = { type: ADD_POST, }; const dummyPost = { id: 2, content: '더미데이터입니다.', User: { id: 1, nickname: '제로초', }, Images: [], Comments: [], }; export default (state = initialState, action) => { switch (action.type) { case ADD_POST: { return { ...state, mainPosts: [dummyPost, ...state.mainPosts], postAdded: true, }; } default: { return { ...state, }; } } }; 코드에 문제가 없는 것 같은데 위와 같이 에러가 뜹니다. post.js파일도 비교해보면서 찾아봤는데도.. 답이 안보입니다.ㅠㅠ
react node.js nodejs redux express next.js Next.js
홍택수
2023-02-10T08:42:08.765Z
댓글 2
좋아요 0
조회수 416
미해결
[리뉴얼] React로 NodeBird SNS 만들기
강의 진도 : 액션과 상태 정리하기 state(=initialState) 중에 me: null 을 저희가 왜 만들어줬었죠?? 길을 잃었습니다. me가 무슨 정보는 담고 있는 걸까요..??
react node.js nodejs redux express next.js Next.js
ea
2023-02-10T06:51:05.126Z
댓글 1
좋아요 0
조회수 241
미해결
[리뉴얼] React로 NodeBird SNS 만들기
서버쪽도 타입스크립트 써도 되나요?? 프론트쪽 타입스크립트로 하고있어가지고요
redux node.js nodejs express react next.js Next.js
오일중
2023-02-09T15:17:46.474Z
댓글 1
좋아요 0
조회수 343
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
안녕하세요 멘토님 항상 좋은 강의 잘 보고 있습니다. 궁금한 점이 생겨서 문의를 드렸는데요, 수업을 하면서는 몰랐는데 타입스크립트와 graphql-codegen에 대하여 강의를 들으면서 09-01 폴더를 10-01로 복사 후, 수업 후반부까지 import 부분에서 계속 빨간줄이 뜨길래 원인을 한참 찾았는데 알고보니 저는 여태까지 컴포넌트를 import 할 때 절대경로를 사용하고 있었습니다. (import 할 때 자동완성 사용) 왜 인지는 모르겠지만 .js 파일까지는 절대 경로를 사용해도 문제가 없었는데 타입스크립트로 변환을 하니까 여태 잘 사용하던 절대경로가 빨간줄이 계속 뜨고 상대경로를 입력하니까 빨간줄이 사라지더라구요. 09-01 .js 실습 파일 (빨간줄 없이 정상작동) 10-01 .tsx 실습 파일 (절대경로 - 빨간줄, 상대경로 - 정상 작동) 이렇게 JS 에서는 되던 절대경로가 TS 에서는 왜 안되는 것인지가 궁금하여 질문드렸습니다. 감사합니다!
node.js Next.js nodejs react next.js graphql seo
FRONTEER
2023-02-09T14:42:59.915Z
댓글 2
좋아요 0
조회수 1485
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
postman 설치후 빈화면을 보여주라고 하시는데 저는 선생님이랑 다른 화면이 나오는데 어떤메뉴로 들어가야 하나요?
node.js Next.js react seo next.js graphql nodejs
김소라
2023-02-09T01:42:35.669Z
댓글 1
좋아요 1
조회수 651
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
강의 보고 따라하는 중인데 yarn generate가 제대로 작동하지 않고 에러가 나옵니다
node.js graphql nodejs seo next.js react Next.js
lar888
2023-02-09T01:40:12.468Z
댓글 2
좋아요 1
조회수 693