inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

172만명의 커뮤니티!! 함께 토론해봐요.

middleware 질문입니다!

미해결

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 댓글 1 좋아요 0 조회수 291

투두리스트 코드

해결됨

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

투두리스트 계속 뭐가 빠진지 모르겠네요 완성된 코드 어디서 볼수있나요? 일일히 찾기에 시간이 너무 걸려요

  • javascript
  • react
  • node.js
1028oob 댓글 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
종효 댓글 2 좋아요 0 조회수 267

포트폴리오 주소 오류 (failed to fetch)

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

포트폴리오 만든 게시판 정보 입력후 등록하기 버튼을 누르면 아래와 같이 오류가 뜹니다. 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
민선 댓글 2 좋아요 0 조회수 333

NextAuth 질문입니다!

해결됨

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 댓글 1 좋아요 0 조회수 422

compose modal 관련 질문입니다. history stack에 강제로 url을 추가 하는 방법이 있나요?

해결됨

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
인쮸 댓글 1 좋아요 0 조회수 174

테스트 오류

해결됨

실전 프론트엔드 테스트 시작하기

테스트가 안됩니다 못찾는다는거 같은데 오류 떠서 그런가요?? 오류 해결 어떻게 하나요

  • javascript
  • react
  • next.js
  • 소프트웨어-테스트
  • Cypress
  • e2e
br 댓글 2 좋아요 1 조회수 261

eslint 다운로드하면서

해결됨

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

eslint다운로드하면서 자꾸 정렬이 안돼요 코드 작성하면 하나하나 띄워쓰기랑 스페이스바 눌러야되고 정렬 정리가 안돼요 ㅠㅠ

  • javascript
  • react
  • node.js
1028oob 댓글 1 좋아요 0 조회수 240

ant-design/icon 적용 시 에러

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

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
임성균 댓글 2 좋아요 0 조회수 234

uncaught runtime error 해결

미해결

처음 만난 리액트(React)

패키지도 새로 설치해보고 챗지피티가 하라는데로 다 해봤는데도 해결이 안되네요 ㅠㅜㅜ 최신 버전맞아요 react랑 react dom 어쩌고랑 create어쩌고에서 문제가 있는 것 같다고 했습니다 ㅠ 어떻게 해결해야하나요

  • HTML/CSS
  • javascript
  • react
ohci0022 댓글 2 좋아요 1 조회수 712

포트폴리오 리뷰 강의 관련이요

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

포트폴리오 리뷰 강의는 먼저 혼자 포트폴리오를 만들고 보는게 좋나요? 아니면 git clone으로 다운받고 어떻게 만들었는지 보고 그냥 넘어가도 되나요?? 리뷰 강의에서 clone으로 설명하는 이유가 궁금해서 여쭤봅니다!

  • react
  • node.js
  • seo
  • graphql
  • next.js
민선 댓글 2 좋아요 0 조회수 244

ReactQuery와 Next를 공부하다가 궁금한 점이 생겼습니다.

해결됨

Next + React Query로 SNS 서비스 만들기

React Query가 사실 데이터를 불러오고 캐싱하는 이유가 가장 큰 것으로 알고있습니다. 하지만, Next14부터는 fatch에 store 기능이 생기면서 캐싱이 되는걸로 알고 있는데, 그러면 데이터 캐싱만을 사용하며 굳이 React Query를 사용하지 않아도 되는건가요?

  • react
  • next.js
  • react-query
  • next-auth
  • msw
이상연 댓글 3 좋아요 0 조회수 629

msw/node의 setupServer를 사용하면 안되나요?

미해결

Next + React Query로 SNS 서비스 만들기

안녕하세요 제로초님, 강의 잘 보던 중 궁금한 점이 생겨 질문 올립니다. 구글링해보면 서버 컴포넌트에 msw를 적용하는 방법으로 msw/node의 setupServer를 많이 사용하는 것 같습니다. msw/node의 setupServer을 사용해도 이슈가 없을지 궁금합니다!

  • react
  • next.js
  • msw
프론터 댓글 2 좋아요 0 조회수 354

StoryBook 관련 궁금 사항입니다.

해결됨

실무에 바로 적용하는 스토리북과 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
김용민 댓글 1 좋아요 1 조회수 278

Checkbox를 누르는데 왜 Editor가 리렌더링되나요?

미해결

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

10.4의 useCallback 강의를 듣는 중에 궁금한 점이 생겼습니다. 하나의 checkbox를 누르면 그에 해당하는 item과 그의 부모 컴포넌트인 List , App 컴포넌트가 리렌더링 되는 것은 이해가 되었습니다.그런데, Editor 컴포넌트는 왜 리렌더링이 되는것인가요?Editor가 props로 받은 onCreate는 App에서 useCallBack으로 선언하였으므로, onCreate의 이전 주소값과 이후 주소값은 동일한 것이라 생각됩니다.

  • javascript
  • react
  • node.js
swghj 댓글 2 좋아요 0 조회수 341

프록시 잘 설정했는데도 404 오류 뜨는 분들

미해결

따라하며 배우는 노드, 리액트 시리즈 - 기본 강의

혹시 다른분들께서 올려주신대로 수정하고 링크도 잘 설정했고 오타도 없는데 콘솔에 계속 "AxiosError: Request failed with status code 404" 에러 나는 분들 계시나요? 404 에러는 보통 페이지가 없기 때문에 나오는 에러로 알고 있는데요 링크 매핑을 잘 했고 보낼때 get 으로도 잘 보냈는데 계속 같은 오류가 나서 끙끙 앓던 중에 네트워크에 cannot get /hello 로 보이더라구요.. 그래서 혹시나 index.js에서 /api/hello 를 /hello 로 수정해서 실행해보니 오류 없이 response 해주더라구요... 결국 링크 문제였습니다...! 혹시나 저같은 분들이 계실까 싶어 해결된 부분 이렇게 남겨봅니다..

  • react
  • node.js
종이상자 댓글 6 좋아요 5 조회수 934

javascript에서 에러가 있어도 렌더링 시키는 방법

해결됨

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

현재 9.2) 투두리스트 업그레이드 3:30 쯤 useState를 useReducer로 변경을 하며 생긴 문제입니다. onCreate함수는 액션 객체로 변경을 하고 화면에서 렌더링되는 것을 보고 있는데, 강의에서는 onUpdate 함수에 setTodos 상태함수가 정의되어 있지 않다는 에러가 있더라도 잘 렌더링이 되고 있습니다. 하지만 제 코드에서는 렌더링이 되지 않고 에러만 발생하게 됩니다. 확장프로그램을 설치했던 걸로 기억하는데 안 되는 이유를 알 수 있을까요? 추가로, 이 때 생기는 에러는 List 컴포넌트에서 map이 정의되지 않았다고 합니다.

  • javascript
  • react
  • node.js
swghj 댓글 1 좋아요 0 조회수 254

원본이 제대로 작동하려면 현재 컴퓨터의 두 글자 지리적 지역을 백 엔드 서비스로 보내야 합니다(예: "미국"). 의 뜻을 알고 싶습니다.

미해결

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 (장고 4.2 기준)

말씀주신 명령프롬프트에서 올려주신 winget install 명령어들을 쳐서 진행하는중 처음부터 문제가 생겼습니다. 원본이 제대로 작동하려면 현재 컴퓨터의 두 글자 지리적 지역을 백 엔드 서비스로 보내야 합니다(예: "미국"). 라는 문구가 뜨며 Y or N 으로 결정 해야하는데 Y를 눌렀다가 어떤식으로 될지 몰라서 질문 올립니다.

  • react
  • python
  • django
  • web-api
  • htmx
메모장 댓글 1 좋아요 0 조회수 652

로컬에서는 카카오 로그인이 되는데 vercel 배포했더니 안되네요 혹시 알려주실 수 있을까요..?

미해결

Next + React Query로 SNS 서비스 만들기

/src/middleware.ts import { auth } from './auth'; import { NextResponse, NextRequest } from 'next/server'; export async function middleware(request: NextRequest) { const session = await auth(); if (request.nextUrl.pathname.startsWith('/login')) { if (session) { return NextResponse.redirect(new URL('/', request.url)); } } if (request.nextUrl.pathname.startsWith('/mypage')) { if (!session) { return NextResponse.redirect(new URL('/login', request.url)); } } if (request.nextUrl.pathname.startsWith('/admin')) { if (session?.user?.name !== 'admin') { return NextResponse.redirect(new URL('/', request.url)); } } } export const config = { matcher: ['/mypage/:path*', '/admin/:path*', '/login'], }; /src/auth.ts import NextAuth from 'next-auth'; import KakaoProvider from 'next-auth/providers/kakao'; export const { handlers: { GET, POST }, auth, } = NextAuth({ pages: { signIn: '/login', }, providers: [ KakaoProvider({ clientId: process.env.KAKAO_CLIENT_ID!, clientSecret: process.env.KAKAO_CLIENT_SECRET!, }), ], secret: process.env.NEXTAUTH_SECRET, }); /src/app/api/auth/[...nextauth]/route.ts export { GET, POST } from '@/auth'; 로컬에서는 되는데 vercel 로 배포 하니까 안되네요.. api/auth/error 로 가지고 Failed to load resource: the server responded with a status of 500 () /api/auth/session 이렇게 오류가 나네요 "next-auth": "^5.0.0-beta.19", 입니다

  • react
  • next.js
  • react-query
  • next-auth
  • msw
kukhyun4 댓글 2 좋아요 0 조회수 829

Next App Route Framer 도입 문의 !

해결됨

Next + React Query로 SNS 서비스 만들기

안녕하세요! 클론하다가 React에서 Framer로 레이아웃을 이전 이후로 나누어서 페이지 전환을 스무스하게 animation을 줬던 기억이 있어서 반영해봤는데요. 위의 페이지 전환 효과를 next 프로젝트에도 반영해보려고 하는데 App Router의 특성? 때문인지 {children} 으로 라우팅을 전달 받기 때문에 이전, 이후가 아닌 공통적인 레이아웃으로 취급되고 명확한 구분(id)가 없기 때문에 부드러운 전환이 잘 안되는 걸까요.. 유추한 내용이 맞을까요..? 타 라이브러리 질문 안받으신다면 죄송함다 ㅠ const Framer = ({ children }: { children: ReactNode }) => { const pathName = usePathname(); return ( <> <AnimatePresence mode="wait" initial={false}> <motion.div key={pathName} initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -20 }} transition={{ duration: 0.5 }} > {children} </motion.div>{" "} </AnimatePresence> </> ); };

  • react
  • next.js
  • react-query
  • next-auth
  • msw
squirrel PARK 댓글 1 좋아요 1 조회수 256

인기 태그

인프런 TOP Writers

주간 인기글