172만명의 커뮤니티!! 함께 토론해봐요.
미해결
Slack 클론 코딩[실시간 채팅 with React]
Login.tsx에서 swr로 호출한 users의 data 값을 return 직전에 console 로그로 찍어봤는데요 네트워크 탭에서는 users 요청은 한번 밖에 없었는데 undefined와 false가 연달아서 찍히더라구요 다른 질문에서 답변해주신 내용을 보니 데이터 로딩중엔 undefined라고 말씀해주셨는데, 맨 처음 컴포넌트가 렌더링될 때 useSWR이 api를 호출하게 되고 이때 console.log(data)는 아직 데이터가 로딩 중이라서 undefined가 찍히게 되고, 이후 데이터 로딩이 완료되면 useSWR이 다시 호출되어? false가 찍히는 프로세스로 이해했는데 맞는걸까요 그렇다면 useSWR로 api호출 시 무조건 최소 2번 렌더링될 수 밖에 없는걸까요? // Login.tsx import React, { useState, useCallback, useEffect } from 'react'; import { TextField, Button } from '@components/index'; import { Link, Navigate } from 'react-router-dom'; import { useInput } from '@hooks/useInput'; import { LogoSlack } from '@assets/icons/'; import axios from 'axios'; import useSWR from 'swr'; import fetcher from '@utils/fetcher'; const Login = () => { // useSWR은 get으로 요청한 데이터를 받아와서 저장한다. // mutate : 내가 원할 때 SWR 호출하기 const { data, error, mutate } = useSWR('http://localhost:3095/api/users', fetcher, { dedupingInterval: 5000, // 주기적으로 호출하지만, dedupingInterval 기간 내에는 캐시에서 불러온다 }); const [logInError, setLogInError] = useState(false); const [email, setEmail, onChangeEmail] = useInput(''); const [password, setPassword] = useInput<string>(''); const onChangePassword = useCallback( (e: React.ChangeEvent<HTMLInputElement>) => { setPassword(e.target.value); }, [email, password, data], ); const onSubmit = useCallback( (e) => { setLogInError(false); axios .post( 'http://localhost:3095/api/users/login', { email, password }, { withCredentials: true, }, ) .then(() => { mutate(); }) .catch((error) => { setLogInError(error.response?.status === 401); }); }, [email, password], ); console.log(data); // if (data) return <Navigate to="/workspace/channel" />; return ( <div className="max-w-[400px] mx-auto px-[20px]"> <h1 className="flex justify-center pt-[60px] pb-[20px]"> <LogoSlack /> <span className="blind">Slack</span> </h1> <TextField label="이메일 주소" type="email" value={email} onChange={onChangeEmail} /> <TextField label="비밀번호" type="password" value={password} onChange={onChangePassword} /> {logInError && <p className="mb-[20px] mt-[-10px] text-red-500 font-normal">로그인 실패</p>} <Button text="로그인" onClick={onSubmit} /> <p className="mt-[10px] text-center"> Slack을 처음 사용하시나요? <Link to="/sign" className="ml-[4px] text-blue-600"> 회원가입 </Link> </p> </div> ); }; export default Login;
react 웹팩 typescript socket.io babel 클론코딩
루룸
2024-07-23T15:02:04.839Z
댓글 1
좋아요 0
조회수 308
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
안녕하세요! 강사님! 우선 훌륭한 강의, 진짜 감사드립니다! 완강 후 필요한 부분은 다시 찾아보고 있는데, 처음 봤을 때도, 다시 볼 때도 이해가 쉽게 될 수 있도록 알려주시려는 게 느껴져요. 그래서 도움이 많이 되었습니다! 강사님 덕분에 자신감이 엄청 생겨서, 개발에 더 큰 흥미가 생겼어요! 늘 감사합니다. 제가 이번에 복습 겸 학습에 활용되었던 프로젝트를 다시 만들어보려고 하는데, next버전 관련하여 질문이 있습니다. 강의에는 next 12버전으로 실습했는데, 실무에서 12버전이 많이 쓰이나요? 버전 12에서 더 공부를 해야 할지, (강의를 듣는 동안 못 따라간 부분은 거의 없으나, 익숙하진 않은 것 같아서 학습이 더 필요한 것 같아요! ) 아니면 현재 강사님께 배운 것을 토대로 앞으로 진행하는 프로젝트는 버전을 높여야 할지 고민이 됩니다.
react node.js seo graphql next.js
맙소사
2024-07-23T12:01:40.499Z
댓글 2
좋아요 1
조회수 264
미해결
한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
안녕하세요! 선생님 배포하고 난 후 id가 null 이라고 뜹니다.. 코드 바꾼 거 없는데 local에서는 잘 작동 하는데 왜 배포후만 그럴까욥..
리액트어려워오요오아오아이아오어아용
2024-07-23T08:56:49.076Z
댓글 1
좋아요 0
조회수 194
미해결
Next + React Query로 SNS 서비스 만들기
자주 질문드리네요 ㅠ middleware에서 login을 유무를 파악하고 로그인으로 리다이렉트하려고합니다 그 이후 로그인이 된다면, 원래 진입하려던 url을 쿼리스트링으로 전달하고 이를 받아 리 다이렉트하는게 목적인데요! 간헐적으로 미들웨어가 실행되지 않는것 같습니다.. 새로고침을 해야지만 리다이렉트가 가능합니다. 클라이언트에서 세션감지하고 useEffect로 router.replace 해도 동일합니다. 제 생각으로는 미들웨어는 admin , contact진입시에는 무조건 실행한다고 알고있었는데 잘못된 거였나요 ㅠ 찾아보니 middleware not Working 이슈가 있는 것같긴한데 원인을 도통모르겠습니다 import { auth } from "@/auth"; import { NextRequest, NextResponse } from "next/server"; export const middleware = async (req: NextRequest) => { const session = await auth(); if (!session) { //권한없으면 login 하라 const url = new URL(`http:localhost:3000/auth/login?redirect=${req.url}`); return NextResponse.redirect(url); } //권한있으면 원래대로 return NextResponse.next(); }; export const config = { matcher: ["/admin/:path*", "/contact/:path*"], }; 혹시! useRouter의 redirect는 client에서 이루어지기 때문에 서버 세션갱신이 되지않아서 상이해지는건가요?! 에서 router.replace(redirectPath); 로 변경 window.location.href = redirectPath;
react next.js react-query next-auth msw
squirrel PARK
2024-07-23T06:34:12.452Z
댓글 1
좋아요 0
조회수 291
미해결
따라하며 배우는 도커와 CI환경 [2023.11 업데이트]
Error response from daemon: The system cannot find the file specified. 이런 오류가 뜹니다 DB 실행하면 . .
aws docker github ci/cd travis-ci 데이터-엔지니어링
kim1234123
2024-07-23T06:23:52.767Z
댓글 1
좋아요 0
조회수 251
해결됨
한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
투두리스트 계속 뭐가 빠진지 모르겠네요 완성된 코드 어디서 볼수있나요? 일일히 찾기에 시간이 너무 걸려요
1028oob
2024-07-23T05:44:05.852Z
댓글 1
좋아요 0
조회수 279
미해결
따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
import React from 'react'; import Dropzone from 'react-dropzone'; import axiosInstance from '../utils/axios'; const FileUpload = ({ onImageChange, images }) => { const handleDrop = async (files) =>{ let formData = new FormData(); const config = { header: {'content-type': 'multipart/form-data'} } formData.append('file', files[0]); try{ const response = await axiosInstance.post('/products/image', formData, config); onImageChange([...images, response.data.fileName]); }catch(error){ console.error(error); } } return ( <div className='flex gap-4'> <Dropzone onDrop={handleDrop}> {({ getRootProps, getInputProps }) => ( <section className='min-w-[300px] h-[300px] border flex items-center justify-center' > <div {...getRootProps()}> <input {...getInputProps()} /> <p className='text-3xl'> + </p> </div> </section> )} </Dropzone> <div className='flex-grow h-[300px] border flex items-center justify-center overflow-x-scroll overflow-y-hidden'> {images.map(image => ( <div key={image}> <img className='min-w-[300px] h-[300px]' src={`${import.meta.env.VITE_SERVER_URL}/${image}`} alt={image} /> </div> ))} </div> </div> ); }; export default FileUpload; 파일도 uploads에 다 들어가는데 파일명만 계속 나와요
react redux node.js 웹앱 mongodb
종효
2024-07-23T04:22:48.855Z
댓글 2
좋아요 0
조회수 269
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
포트폴리오 만든 게시판 정보 입력후 등록하기 버튼을 누르면 아래와 같이 오류가 뜹니다. new:1 Access to fetch at ' http://backend-practice.codebootcamp.co.kr/graphql ' from origin ' http://localhost:3004 ' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value ' http://localhost:3000 ' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. 코드상에는 문제가 없는 거같은데.. 주소 확인 부탁드립니다.. ㅠ import { gql, useMutation } from "@apollo/client"; import { useRouter } from "next/router"; import React, { useState } from "react"; import { Address, ButtonWrapper, Contents, ImageWrapper, InputWrapper, Label, OptionWrapper, Password, RadioButton, RadioLabel, SearchButton, Subject, SubmitButton, Title, UploadButton, Wrapper, Writer, WriterWrapper, Youtube, Zipcode, ZipcodeWrapper, } from "../../../styles/boardsNew"; const CREATE_BOARD = gql` mutation createBoard($createBoardInput: CreateBoardInput!) { createBoard(createBoardInput: $createBoardInput) { _id } } `; export default function BoardsNewPage() { const router = useRouter(); const [writer, setWriter] = useState(""); const [password, setPassword] = useState(""); const [title, setTitle] = useState(""); const [contents, setContents] = useState(""); const [writerError, setWriterError] = useState(""); const [passwordError, setPasswordError] = useState(""); const [titleError, setTitleError] = useState(""); const [contentsError, setContentsError] = useState(""); const [createBoard] = useMutation(CREATE_BOARD); const onChangeWriter = (event) => { setWriter(event.target.value); if (event.target.value !== "") { setWriterError(""); } }; const onChangePassword = (event) => { setPassword(event.target.value); if (event.target.value !== "") { setPasswordError(""); } }; const onChangeTitle = (event) => { setTitle(event.target.value); if (event.target.value !== "") { setTitleError(""); } }; const onChangeContents = (event) => { setContents(event.target.value); if (event.target.value !== "") { setContentsError(""); } }; const onClickSubmit = async () => { if (!writer) { setWriterError("작성자를 입력해주세요."); } if (!password) { setPasswordError("비밀번호를 입력해주세요."); } if (!title) { setTitleError("제목을 입력해주세요."); } if (!contents) { setContentsError("내용을 입력해주세요."); } if (writer && password && title && contents) { try { const result = await createBoard({ variables: { createBoardInput: { writer, password, title, contents, }, }, }); console.log(result.data.createBoard._id); router.push(`/boards/${result.data.createBoard._id}`); } catch (error) { alert(error.message); } } }; return ( <Wrapper> <Title>게시글 등록</Title> <WriterWrapper> <InputWrapper> <Label>작성자</Label> <Writer type="text" placeholder="이름을 적어주세요." onChange={onChangeWriter} /> <div style={{ color: "red" }}>{writerError}</div> </InputWrapper> <InputWrapper> <Label>비밀번호</Label> <Password type="password" placeholder="비밀번호를 작성해주세요." onChange={onChangePassword} /> <div style={{ color: "red" }}>{passwordError}</div> </InputWrapper> </WriterWrapper> <InputWrapper> <Label>제목</Label> <Subject type="text" placeholder="제목을 작성해주세요." onChange={onChangeTitle} /> <div style={{ color: "red" }}>{titleError}</div> </InputWrapper> <InputWrapper> <Label>내용</Label> <Contents placeholder="내용을 작성해주세요." onChange={onChangeContents} /> <div style={{ color: "red" }}>{contentsError}</div> </InputWrapper> <InputWrapper> <Label>주소</Label> <ZipcodeWrapper> <Zipcode placeholder="07250" /> <SearchButton>우편번호 검색</SearchButton> </ZipcodeWrapper> <Address /> <Address /> </InputWrapper> <InputWrapper> <Label>유튜브</Label> <Youtube placeholder="링크를 복사해주세요." /> </InputWrapper> <ImageWrapper> <Label>사진첨부</Label> <UploadButton>+</UploadButton> <UploadButton>+</UploadButton> <UploadButton>+</UploadButton> </ImageWrapper> <OptionWrapper> <Label>메인설정</Label> <RadioButton type="radio" id="youtube" name="radio-button" /> <RadioLabel htmlFor="youtube">유튜브</RadioLabel> <RadioButton type="radio" id="image" name="radio-button" /> <RadioLabel htmlFor="image">사진</RadioLabel> </OptionWrapper> <ButtonWrapper> <SubmitButton onClick={onClickSubmit}>등록하기</SubmitButton> </ButtonWrapper> </Wrapper> ); } import { gql, useQuery } from "@apollo/client"; import { useRouter } from "next/router"; import { Avatar, AvatarWrapper, Body, BottomWrapper, Button, CardWrapper, Contents, CreatedAt, Header, Info, Title, Wrapper, Writer, } from "../../../styles/boardsDetail"; export const FETCH_BOARD = gql` query fetchBoard($boardId: ID!) { fetchBoard(boardId: $boardId) { _id writer title contents createdAt } } `; export default function BoardDetailPage() { const router = useRouter(); const { data } = useQuery(FETCH_BOARD, { variables: { boardId: router.query.boardId }, }); return ( <Wrapper> <CardWrapper> <Header> <AvatarWrapper> <Avatar src="/images/avatar.png" /> <Info> <Writer>{data?.fetchBoard?.writer}</Writer> <CreatedAt> {new Date(data?.fetchBoard?.createdAt).toLocaleDateString()} </CreatedAt> </Info> </AvatarWrapper> </Header> <Body> <Title>{data?.fetchBoard?.title}</Title> <Contents>{data?.fetchBoard?.contents}</Contents> </Body> </CardWrapper> <BottomWrapper> <Button>목록으로</Button> <Button>수정하기</Button> <Button>삭제하기</Button> </BottomWrapper> </Wrapper> ); } import "../styles/globals.css"; import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client"; export default function App({ Component, pageProps }) { const client = new ApolloClient({ uri: "http://backend-practice.codebootcamp.co.kr/graphql", cache: new InMemoryCache(), }); return ( <ApolloProvider client={client}> <Component {...pageProps} /> </ApolloProvider> ); }
react node.js seo graphql next.js
민선
2024-07-23T01:40:23.990Z
댓글 2
좋아요 0
조회수 334
해결됨
Next + React Query로 SNS 서비스 만들기
NextAuth에서의 session token을 통해 사용자정보랑 세션쿠키를 전달하고있는데요. 만일 access Token이랑 Refresh Token으로 관리를 한다고 한다면, Session Token도 반 강제적으로 사용해야 하는 것같은데 이럴때는 3개의 토큰을 만료일을 컨트롤 해야하는건가요..? 예로 access 30분 session 1시간 refresh 7일 이렇게 가져가서 엑세스와 세션 두가지의 토큰을 다 갱신해주어야 하는건지 아니면 제가 지금 이상한 프로세스를 생각중인지 모르겠네요 .. NextAuth에 리프래시 엑세스토큰을 통상적으로 어떻게쓰는지가 궁금합니다.. session token때문에 너무 혼동이오네요..
react next.js react-query next-auth msw
squirrel PARK
2024-07-22T17:45:54.647Z
댓글 1
좋아요 0
조회수 423
해결됨
Next + React Query로 SNS 서비스 만들기
만약 새창에서 /compose/tweet을 열었을 때 X버튼을 누르면 back()으로 동작되어 창이 닫히지 않거나, 이 전페이지 (트위터 창이 아닌 다른 창)으로 이동하는 이슈가 발생하여 x.com 은 어떻게 동작되는지 확인했는데, 이미지 처럼 새창에서 /compose/tweet을 열었을 때, history에 home url이 추가가 되어 뒤로가기를 눌렀을 때 홈으로 돌아가는 것 같습니다. 이렇게 hitory url을 제어하는 방법이 있을까요? 구글링해도 정보를 얻을 수 없어 글 올립니다 ㅠ
react next.js react-query next-auth msw
인쮸
2024-07-22T12:24:01.155Z
댓글 1
좋아요 0
조회수 174
해결됨
실전 프론트엔드 테스트 시작하기
테스트가 안됩니다 못찾는다는거 같은데 오류 떠서 그런가요?? 오류 해결 어떻게 하나요
javascript react next.js 소프트웨어-테스트 Cypress e2e
br
2024-07-22T08:37:08.638Z
댓글 2
좋아요 1
조회수 262
해결됨
한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
eslint다운로드하면서 자꾸 정렬이 안돼요 코드 작성하면 하나하나 띄워쓰기랑 스페이스바 눌러야되고 정렬 정리가 안돼요 ㅠㅠ
1028oob
2024-07-22T08:16:08.414Z
댓글 1
좋아요 0
조회수 240
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
import { UpCircleOutlined } from "@ant-design/icons"; export default function LibraryIconPage() { return ( <> <UpCircleOutlined /> </> ); } ant-design/icons 5.0.1 버전 다운로드 받고 실행하니까 이런 에러가 뜨는데 어떤 문제일까요..?
react node.js seo graphql next.js
임성균
2024-07-22T07:00:22.439Z
댓글 2
좋아요 0
조회수 237
미해결
처음 만난 리액트(React)
패키지도 새로 설치해보고 챗지피티가 하라는데로 다 해봤는데도 해결이 안되네요 ㅠㅜㅜ 최신 버전맞아요 react랑 react dom 어쩌고랑 create어쩌고에서 문제가 있는 것 같다고 했습니다 ㅠ 어떻게 해결해야하나요
ohci0022
2024-07-22T00:47:45.627Z
댓글 2
좋아요 1
조회수 713
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
포트폴리오 리뷰 강의는 먼저 혼자 포트폴리오를 만들고 보는게 좋나요? 아니면 git clone으로 다운받고 어떻게 만들었는지 보고 그냥 넘어가도 되나요?? 리뷰 강의에서 clone으로 설명하는 이유가 궁금해서 여쭤봅니다!
react node.js seo graphql next.js
민선
2024-07-21T16:18:18.551Z
댓글 2
좋아요 0
조회수 244
해결됨
Next + React Query로 SNS 서비스 만들기
React Query가 사실 데이터를 불러오고 캐싱하는 이유가 가장 큰 것으로 알고있습니다. 하지만, Next14부터는 fatch에 store 기능이 생기면서 캐싱이 되는걸로 알고 있는데, 그러면 데이터 캐싱만을 사용하며 굳이 React Query를 사용하지 않아도 되는건가요?
react next.js react-query next-auth msw
이상연
2024-07-21T15:59:18.757Z
댓글 3
좋아요 0
조회수 631
미해결
Next + React Query로 SNS 서비스 만들기
안녕하세요 제로초님, 강의 잘 보던 중 궁금한 점이 생겨 질문 올립니다. 구글링해보면 서버 컴포넌트에 msw를 적용하는 방법으로 msw/node의 setupServer를 많이 사용하는 것 같습니다. msw/node의 setupServer을 사용해도 이슈가 없을지 궁금합니다!
프론터
2024-07-20T10:27:22.699Z
댓글 2
좋아요 0
조회수 357
미해결
readable_code:: 따라하면 끝나있는 C++ 개발환경 설정 A to Z
안녕하세요. 과정을 진행하는 중 질문이 생겨 남겨봅니다. VSCode Extension에서 CMake Tools를 설치하였지만 설명하신대로 Clang 설정 화면이 나오지 않아 VSCode 설정에서 설정해보려고 하는데 어떤 설정을 지정해야 하는지 잘 모르겠습니다.
Gary.J
2024-07-20T07:12:27.543Z
댓글 1
좋아요 0
조회수 237
해결됨
실무에 바로 적용하는 스토리북과 UI 테스트
Next.js를 사용하는 경우 이미지 최적화를 위해 next/image 에서 제공하는 Image 컴포넌트를 사용합니다! 이를 활용해서, 스토리북 컴포넌트를 만들 경우, React에서 이를 활용할 수 있을지 궁금합니다. 현재, React-Native-Cli에서 프로젝트를 진행하고 있습니다. React-Native-Cli(View, Text, Pressable)와, React, Next에서 모두 활용 가능한, 공용 스토리북 컴포넌트를 현실적으로 만들 수 있는지, 실무에서는 각각 따로 분리해서 개발을 진행하는지 여부가 궁금합니다! 타입스크립트로 만든 스토리북 패키지를, 자바스크립트를 활용한 (타입스크립트를 사용하지 않는) 프로젝트에서 활용가능한지도 궁금합니다! 프로젝트를 진행하면, 스토리북과 함께 한개의 레포지토리로 관리하는 것이 좋은지, 아니면, 따로 분리해서 두개의 레포지토리로 관리하는 것이 좋은지 궁금합니다! 개발 시작시, 먼저 스토리북으로 컴포넌트를 제작 후, 개발을 진행하는 것이 좋은지, 아니면, 개발을 진행해가며, 그때 그떄 공용 컴포넌트로 쓰일 만한 것들을 스토리북으로 만들어나가는 것이 좋은지 강사님의 경험상 괜찮은 방법을 알려주시면 감사하겠습니다!!
react typescript tailwind-css storybook ui-testing
김용민
2024-07-20T05:18:49.321Z
댓글 1
좋아요 1
조회수 279
미해결
포트폴리오 초간단 배포하기
백엔드 서버에는 nginx를 설치하지 않았는데, 도메인 등록시 :8080 포트는 어떻게 처리해야 하는지 궁금합니다. 도메인 등록후에 'www.도메인:8080' 으로 접속해야 접속이 되어서 질문드립니다. nginx 설치하고, 거기서 jar 파일을 업로드 하면 해결 될까요?
이용화
2024-07-20T01:02:59.872Z
댓글 1
좋아요 1
조회수 658