묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결이득우의 언리얼 프로그래밍 Part2 - 언리얼 게임 프레임웍의 이해
뷰포트에서 화면이 아래 위로 밖에 안움직입니다
움직임도 잘되고 v키를 눌러 시점 전환도 잘되는데 마우스가 오른쪽이나 왼쪽으로 가면 화면이 그쪽으로 돌아가지 않고 아래 위로만 회전합니다 혹시 마우스 관련 설정이 잘못된걸까요?
-
미해결딥러닝 CNN 완벽 가이드 - TFKeras 버전
보스턴 집값 예제가 실행이 안 됩니다.
/opt/conda/lib/python3.10/site-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function load_boston is deprecated; `load_boston` is deprecated in 1.0 and will be removed in 1.2. The Boston housing prices dataset has an ethical problem. You can refer to the documentation of this function for further details. The scikit-learn maintainers therefore strongly discourage the use of this dataset unless the purpose of the code is to study and educate about ethical issues in data science and machine learning. In this special case, you can fetch the dataset from the original source:: import pandas as pd import numpy as np data_url = "http://lib.stat.cmu.edu/datasets/boston" raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None) data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]]) target = raw_df.values[1::2, 2] Alternative datasets include the California housing dataset (i.e. :func:`~sklearn.datasets.fetch_california_housing`) and the Ames housing dataset. You can load the datasets as follows:: from sklearn.datasets import fetch_california_housing housing = fetch_california_housing() for the California housing dataset and:: from sklearn.datasets import fetch_openml housing = fetch_openml(name="house_prices", as_frame=True) for the Ames housing dataset. warnings.warn(msg, category=FutureWarning)예전에 어떤 사람이 같은 내용으로 문의를 한 적이 있습니다. 그런데 답변의 내용대로 해도 해결이 안 됩니다. 사이킷런 버전 1.0.2로 바꾸고 run -> restart & clear cell output 누르고 다시 들어가도 이런 오류가 나옵니다.어떻게 하면 좋을까요?
-
해결됨[자바/Java] 문과생도 이해하는 DFS 알고리즘! - 입문편
재귀대신 스택으로 구현하면 안될까요?
이 문제의 재귀는 이해가 됬지만, 다른 문제들에서 마주치는 재귀함수들은 손이 잘 안가고, 항상 남의코드를 봐야만 이해가 되더라구요.여기서 dfs함수를 스택으로 구현하면 라인이 더 길어져 재귀보다는 깔끔하지가 않은데, 이해 및 구현이 쉬운거 보다 명확한거 같은데, 코딩테스트의 재귀들은 모두 스택으로 구현하면 어떨지 궁금합니다.
-
미해결실습으로 배우는 프로메테우스 - {{ x86-64, arm64 }}
6.3 강의 질문.
안녕하세요6.3 harbor를 configuration에 등록하는 부분에서job부분을- job_name: harbormetrics_path: /metricsrelabel_configs:- source_labels:- __address__action: keeptarget_label: __address__regex: (.+?)(\\:\\d+)?replacement: $1 위와 같이 kube-proxy처럼 등록해보려고 했는데 target에는 내용이 보이질 않아서요.혹시 안되는 이유를 알 수 있을까요?(harbor의 address label이 IP:port여서 replacement에는 포트는 따로 쓰진않았습니다.)
-
해결됨독하게 시작하는 C 프로그래밍
예제문제와 유사한 문제 풀이 사이트
안녕하세요! 널개님 강의 듣고있는 수강생입니다.강의 내에 나와있는 예제문제 외에도 실습을 통해 실력을 향상시키고 싶습니다.혹시 실습을 할 수 있는 사이트를 추천해주실 수 있을까요?이론강의는 널개님 강의를 통해 충족이 되지만 실습은 아직도 부족하네요ㅠㅠ실습을 통해서도 배우는게 많다 생각하여 문의드립니다.항상 시간이 아깝지않은 강의해주셔서 감사합니다!
-
미해결
프로젝트 리팩토링
제가 포트폴리오를 목적으로 스프링부트 즉, 백엔드를 맡았고 리액트와 진행했는데 프로젝트는 완성이 되었지만 리팩토링을 하고 있으면 좋을거 같은 기능들을 추가하려고 할 때 그러면 백엔드에서는 만들지만 화면은 구성을 못하니 그냥 건들지 말아야 할까요 아니면 백엔드에서 구현하더라도 그냥 포폴에는 언급하지 말아야 하나요? 포트폴리오 용으로 만들고 나서 코드를 가독성 있게 리팩토링하고 갑자기 아 이런 기능이 있었으면 좋았겠는데 그런 생각들이 들어서 백엔드에서라도 구현할까 하다가 연습용이면 모를까 포폴용이라 어떻게 해야할지 헷갈리네요
-
미해결스프링 핵심 원리 - 기본편
섹션6. 필터에서 beanA를 찾을 수 없음
@MyIncludeComponent public class BeanA { }@MyExcludeComponent public class BeanB { }package hello.core.scan.filter; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import static org.assertj.core.api.Assertions.*; import static org.springframework.context.annotation.ComponentScan.*; public class ComponentFilterAppConfigTest { @Test void filterScan() { ApplicationContext ac = new AnnotationConfigApplicationContext(ComponentFilterAppConfig.class); BeanA beanA = ac.getBean("beanA", BeanA.class); assertThat(beanA).isNotNull(); } @Configuration @ComponentScan( includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class), excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class) ) static class ComponentFilterAppConfig { } }강의와 똑같이 따라친 해당 코드에서 org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'beanA' available 에러가 계속 발생합니다. 그래서 아래 코드처럼 BeanA 클래스와 BeanB클래스에 @Component 애노테이션을 추가하였더니 잘 작동합니다. @MyIncludeComponent @Component public class BeanA { } @MyExcludeComponent @Component public class BeanB { } 그런데 이 경우에는 또 하단의 Assertions.thorws 검증 코드가 제대로 작동하지 않습니다. ㅠ .... assertThrows( NoSuchBeanDefinitionException.class, () -> ac.getBean("beanB", BeanB.class)); 그래서 하단 코드처럼 BeanA에만 @Component를 붙이고 BeanB에는 @Component를 붙이지 않으면 테스트 코드가 올바르게 작동합니다... 원인을 알 수 있을까요? @MyIncludeComponent @Component public class BeanA { }@MyExcludeComponent public class BeanB { } BeanA, BeanB, MyExcludeComponent, MyIncludeComponent, ComponentFilterAppConfigTest 모두 테스트의 filter 패키지에 있습니다.
-
해결됨넓고 얕게 외워서 컴공 전공자 되기
Native Code 질문입니다!
안녕하세요! Native Code와 Managed Code 관련해서 질문을 남겨 봅니다! C언어의 컴파일 과정에서, 목적 파일이 생성 되지않습니까?이러한 목적 파일이, 링킹 과정을 거치면 실행 파일이 되는걸로 알고 있습니다 여기서 질문입니다!실행 파일의 적힌 실행 코드가, Native Code와 같은 의미인가요?JVM과 같이, 소프트웨어 CPU(virtual machine)를 예로 들었을 때, 컴파일 과정을 거치고, 최종적으로 만들어진 실행파일의 적힌 코드는 Managed code라고 보면 되는걸까요? 감사합니다!
-
해결됨김영한의 실전 자바 - 기본편
다형성과 캐스팅 질문입니다
처음엔 자식타입이 부모타입보다 더 큰 범위라서 부모 인스턴스는 자식 인스턴스를 참조할 수 있다고 이해했습니다. 또한 강의자료에도 자식 클래스를 참조할 때 자식 인스턴스 안에 부모 인스턴스의 부분과 자식인스턴스의 부분이 나뉘어져있는거라고 나와 있어 그대로 이해했었는데요. 강의에선부모가 자식을 담을 수 있다 (O)자식은 부모를 담을 수 없다(O)이렇게 되어있어 헷갈려서 질문드립니다...(+ 그리고 다운캐스팅은 복사한 값을 캐스팅하는 것이므로 일시적으로만 실행되는게 맞나요?)=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
th:class 부분 th:if /th: classappend
위 코드에서 th: class= ${errors?.containsKey('itemName')} ? ~~~ 를 if 조건식으로 참 거짓 구분하여 참이면 클래스 뒤에 append를 해주는 방식으로 해주었는데 이방식으로 하면 아예 상품명 공간이 사라지네요 ㅜ 다른방식으로도 해보고 싶은데 강사님이 알려주신 th:class 밖에 없는것일까요?타임리프 기본 문법을 다시 보면서 변형해보고있는데 잘 안되서요 😅 th:if="${errors?.containsKey('itemName')}" th:classappend="field error"
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
강의 자료 오타 제보합니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]3. 회원 관리 예제 - 백엔드 개발.pdf5번째 페이지MemoryMemberRepositoryTest 클래스의 save() 메서드 부분이 이렇게 되어 있습니다. 마지막 줄이 수정이 필요해 보입니다.@Test public void save() { //given Member member = new Member(); member.setName("spring"); //when repository.save(member); //then Member result = repository.findById(member.getId()).get(); (result).isEqualTo(member); }
-
해결됨넓고 얕게 외워서 컴공 전공자 되기
가상메모리 관련잘문입니다
Hdd의 용량을 많이 사용했을때 컴퓨터가 느려졌다 느껴지게되는것이 가상메모리로 할당할 영역이 줄어들어서인가요? 같은 양의 연산을 할 때 메모리의 용량이 적을수록 할당하는 가상메모리의 용량이 커지나요?
-
해결됨2주만에 통과하는 알고리즘 코딩테스트 (2024년)
[활용(바텀업DP)] 8:08, 10:55
안녕하십니까 코딩센세! 이번에도 어김없이 질문 드리고 싶은 부분이 있어서 질문글을 남겨봅니다. 활용(바텀업 DP) 수업에서, 8:08초와 10:55초 에서 작성하신 if문이 잘 와닿지가 않습니다. 8:08초의 경우, if idx+ interview[idx][0] > N 으로 작성하셨는데요. 설명 역시 논리적으로 다가왔습니다. 당연히 문제에서 주어진 N의 범위보다 크다면 인덱싱이 불가능할테니 idx보다 더 뒤에 있는 dp[idx+1]의 값으로 할당하는 거라고 이해했습니다. 문제는 10:55초 입니다. 작성하신 코드는 if weight < B 인데요. 부연 설명은 "가방의 무게보다 작으면 예외 처리를 한다"라고 이해했습니다. 문제의 요구사항에 따르면 가방의 무게보를 초과했을 때 예외처리를 해야 하지 않나? 라는 의문이 들었는데요. 아직 의문을 해결하지 못하여 선생님의 코드가 잘 이해가 되지 않는 상태에 있습니다... 저의 질문을 읽어주신다면, if weight < B 라고 조건을 걸어야 하는 부분에 대해 조금 더 상세한 설명을 부탁드립니다! p.s. 선생님 혹시 7강에 대한 정답 코드는 볼 수 없는건가요? 수업자료에 작성되어 있지 않아서 문의드립니다.
-
미해결이득우의 언리얼 프로그래밍 Part2 - 언리얼 게임 프레임웍의 이해
21 : 41 OnGameClear OnGameOver 이벤트 노드
앞서 만든 코드에서는 OnGameClearCpp, OnGameOverCpp 이름으로 나오도록 했는데 미리 만드신것에선 이름을 다르게 지으신건가요?OnGameClear, OnGameOver이름이 다르길래 질문드립니다. +수정강의 뒤에 내용을 듣다보니 OnGameClearCpp, OnGameOverCpp 도 가져와 연결시켜주네요..미리만들어진것말고 제가 직접 만들어보고 있는데 저노드가 안보이는데 어떻게 추가를하면 될까요?
-
미해결토비의 스프링 부트 - 이해와 원리
ApplicationRunner 가 동작하지 않는 이유
테스트 환경에서는 application.properties를 읽지 않고 ApplicationRunner가 동작하지 않는다고 하셨습니다. 그래서 @TestPropertySource로 설정 파일을 넣어줬는데요 이게 동작하지 않는 이유는 테스트 환경은 스프링을 확장해서 스프링 컨테이너를 띄우고 구성 정보 클래스를 집어넣어서 빈 오브젝트만 등록하기 때문이 맞을까요 ? SpringApplication.run은 테스트 환경과 다르게 스프링 컨테이너를 띄우고 템플릿 매서드로 컨테이너를 띄우고 구성 정보 클래스를 활용해서 빈 오브젝트를 등록하는 거 외에 추가적인 Ruuner 나 Property 파일을 읽는 작업을 별도로 하기 때문인거죠 ?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
리트윗 라우터에서 설정한 리트윗 검사가 되지 않습니다!(중복 리트윗 체크 및 본인 게시글 리트윗이 막아지지 않는 문제)
안녕하세요! React로 NodeBird SNS 만들기섹션4 리트윗하기 강의 시청 중 발생한 에러에 대해 질문 드립니다!항상 강의 잘 보고 있습니다! 제로초님 감사합니다! [리트윗 라우터에서 설정한 리트윗 검사]1. 자기 게시글을 리트윗한 경우2. 자기 게시글을 리트윗한 다른 게시글을 다시 자기가 리트윗한 경우3. 이미 리트윗한 게시글을 또 리트윗 하는 경우(중복 리트윗) 여러 개의 게시글을 가져오는 라우터에서 리트윗한 게시글, 작성자, 이미지 모델을 넣었으며,게시글 Reducer에서 리트윗 실패 시 실패 확인을 'draft.retweetError = action.error;'로 확인하였습니다.게시글 Saga에서도 리트윗 요청 실패 시 실패 결과를 'error: err.response.data'로 설정했습니다.★ 프론트, 백엔드 쪽 터미널과 콘솔, 리덕스, 네티워크 쪽에 오류가 없음을 확인하였습니다.코드 오타가 원인이라고 파악해 제로초님의 깃허브와 제 코드를 비교하며 확인했으나원인을 찾을 수 없어 질문 올립니다. 아래는 가장 의심되는 코드 입니다.중요하지 않은 코드는 '. . .' 으로 생략하였습니다.front/pages/index.js // React 라이브러리 훅 불러오기 import React, { useEffect } from 'react'; . . . // 홈 컴포넌트(사용자 정의 태그) const Home = () => { const dispatch = useDispatch(); const { me } = useSelector((state) => state.user); const { mainPosts, hasMorePosts, loadPostsLoading, retweetError } = useSelector((state) => state.post); . . . // 리트윗 실패 시 리트윗 에러 alert 창 띄우기 useEffect(() => { if (retweetError) { alert(retweetError); } }, [retweetError]);front/components/PostCard.js따로 게시글을 리트윗 실패(RETWEET_FAILURE) 액션을 디스패치 해야 하는지 의심이 들었습니다!// 게시글 카드 컴포넌트(사용자 정의 태그) const PostCard = ({ post }) => { . . . // 리트윗 버튼 콜백 함수 const onRetweet = useCallback(() => { // 로그인을 안했을 때 '로그인이 필요합니다.' alert 창 띄우기 if (!id) { return alert('로그인이 필요합니다.'); } /* 리트윗 요청 액션 객체 디스패치 */ return dispatch({ type: RETWEET_REQUEST, // 리트윗 요청 액션 data: post.id, // 게시글 아이디 }); }, [id]); . . . return ( <div style={{ marginBottom: '20px' }}> <Card /* ---------- 이미지 : 이미지는 1개 이상 ---------- */ cover={post.Images[0] && <PostImages images={post.Images} />} /* ---------- 액션 버튼 ---------- */ actions={[ /* ---------- 리트윗 버튼 ---------- */ <RetweetOutlined key="retweet" onClick={onRetweet} />, . . . ]} /* 카드 제목 */ title={post.RetweetId // 리트윗 게시글이면 게시글 사용자 닉네임님이 리트윗 하셨습니다. 제목 써주기 ? `${post.User.nickname}님이 리트윗 하셨습니다.` // 일반 게시글이면 제목 안 써주기 : null } . . . > {/* Card 닫기 */} {/* ---------- 리트윗 게시글 ---------- */} {post.RetweetId && post.Retweet ? ( <Card /* ---------- 이미지 : 이미지는 1개 이상 ---------- */ cover={post.Retweet.Images[0] && <PostImages images={post.Retweet.Images} />} > <Card.Meta // 메인 게시글 리트윗한 사용자 닉네임의 첫 번째 글자를 // 아바타 아이콘으로 표시 avatar={<Avatar>{post.Retweet.User.nickname[0]}</Avatar>} // 메인 게시글 리트윗한 게시글 작성자 이름 title={post.Retweet.User.nickname} // 메인 게시글 게시글 콘텐츠 description={<PostCardContent postData={post.Retweet.content} />} /> </Card> ) : ( /* ---------- (리트윗을 하지않은) 일반 게시글 ---------- */ <Card.Meta // 메인 게시글 사용자 닉네임의 첫 번째 글자를 아바타 아이콘으로 표시 avatar={<Avatar>{post.User.nickname[0]}</Avatar>} // 메인 게시글 작성자 이름 title={post.User.nickname} // 메인 게시글 콘텐츠 description={<PostCardContent postData={post.content} />} /> )} </Card> back/routes/post.js// 리트윗 라우터 router.post('/:postId/retweet', isLoggedIn, async (req, res, next) => { // POST /post/동적 히든/retweet try { /* 존재하지 않는 게시글이 있는지 검사하는 함수 */ const post = await Post.findOne({ where: { id: req.params.postId }, // 모델 가져오기 include: [{ model: Post, as: 'Retweet', // as: 'Retweet'으로 include를 해주면 post.retweet이 생긴다. }], }); /* ---------- 만약 존재하지 않는 게시글이 있다면 400번대 에러 출력 ---------- */ if (!post) { return res.status(403).send('존재하지 않는 게시글입니다.'); } /* 자기 게시글을 리트윗하기 or 자기 게시글을 리트윗한 다른 게시글을 다시 자기가 리트윗하기 막기 */ if (req.user.id === post.UserId || (post.Retweet && post.Retweet.UserId === req.user.id)) { return res.status(403).send('자신의 글은 리트윗할 수 없습니다.'); } // 리트윗할 Id : 리트윗한 게시글이면 리트윗 아이디 사용 or 아니면 게시글 아이디 사용 const retweetTargetId = post.RetweetId || post.id; /* 이미 리트윗한 게시글을 또 리트윗하는지 검사하는 함수(두 번 리트윗 막기) */ const exPost = await Post.findOne({ where: { UserId: req.user.id, RetweetId: retweetTargetId, }, }); /* ----- 만약 이미 리트윗한 게시글을 또 리트윗한다면 400번대 에러 출력 ----- */ if (exPost) { return res.status(403).send('이미 리트윗했습니다.'); } /* await : 실제로 데이터가 들어감, create : 테이블 안에 데이터를 넣음 */ const retweet = await Post.create({ UserId: req.user.id, RetweetId: retweetTargetId, content: 'retweet', // 게시글 모델에서 allowNull을 false로 설정했기 때문에 게시글 콘텐츠가 필수다. }); /* ---------- 내가 어떤 게시글을 리트윗했는지 찾는 함수 ---------- */ const retweetWithPrevPost = await Post.findOne({ where: { id: retweet.id }, // 모델 가져오기 include: [{ /* ---------- 리트윗한 게시글 ---------- */ model: Post, as: 'Retweet', // 리트윗한 게시글이 post.Retweet으로 담긴다. // 모델 가져오기 include: [{ /* ---------- 리트윗한 게시글의 작성자 ---------- */ model: User, attributes: ['id', 'nickname'], // id, nickname 데이터만 가져오기 }, { /* ---------- 리트윗한 게시글의 이미지 ---------- */ model: Image, }] }, { /* ---------- 게시글 작성자 ---------- */ model: User, attributes: ['id', 'nickname'], // id, nickname 데이터만 가져오기 }, { /* ---------- 게시글 좋아요 누른 사람들 ---------- */ model: User, as: 'Likers', attributes: ['id'], // id 데이터만 가져오기 }, { /* ---------- 게시글 이미지 ---------- */ model: Image, }, { /* ---------- 게시글 답글 ---------- */ model: Comment, // 모델 가져오기 include: [{ /* ---------- 게시글 답글의 작성자 ---------- */ model: User, attributes: ['id', 'nickname'], // id, nickname 데이터만 가져오기 }], }], }); /* 게시글 작성 성공 시 어떤 게시글을 리트윗 했는지에 대한 정보를 프론트로 돌려주기 */ res.status(201).json(retweetWithPrevPost); /* ---------- 에러 캐치 ---------- */ } catch (error) { console.error(error); next(error); } }); +++ 줄바꿈이 되지 않은 문제를 수정하였습니다.
-
미해결이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해
8강 16:00분 class UCard* card; -> 컴포지션을 사용과 NewObject를 이용한 생성의 구분에 대한 질문
해당 코드에서UPROPERTY()TObjectPtr<class UCard> Card;컴포지션을 사용한 Card와UPROPERTY()UCard* Card = NewObject<UCard>();동적으로 생성한 Card의 정확한 차이와 구분을 모르겠습니다.어떻게 구분해서 사용해야 할까요?
-
미해결코딩으로 학습하는 GoF의 디자인 패턴
Spring Security 의 ProviderManager (AuthenticationManager) 도 옵저버 패턴을 사용하고 있다고 볼 수 있을까요?
안녕하세요 강사님! 우선 양질의 강의 잘 듣고 있다는 말씀 드리고 싶습니다. Spring Security 에서 AuthenticationProvider 를 찾아서 인증을 위임하는 역할을 수행하는 ProviderManger 도 옵저버 패턴을 사용하고있다고 볼 수 있을까요? ProviderManager (AuthenticationManager) 에서 AuthenticationProvider 들을 가져온후 이들을 순회하며 인증위임을 시키는 코드입니다단순히 supports() 를 통해 인증을 위임시킬 AuthenticationProvider 들을 골라내는 것뿐, 이것도 옵저버 패턴이 적용된 예인지 알고 싶습니다.
-
미해결스프링 핵심 원리 - 고급편
OrderControllerV1 인터페이스에 @RequestMapping 선언 시 404 not found 뜨시는 분들
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]저와 같은 문제를 겪을까 포스팅 합니다.스프링 부트 3.2 버전 사용 중이며, @RequestMapping 어노테이션 사용 시에 404 not found가 반환될텐데, 해당 부분 @RestController로 변경 시 정상적으로 ok 반환됩니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
인피니트 스크롤링 적용시 LOAD_POST_REQUEST 두번 찍히는 문제
안녕하세요 선생님 상황)인피니트 스크롤링 적용시 LOAD_POST_REQUEST 두번 찍히는 상황인데 이거의 원인과 해결방법을 어떻게 찾을 수 있을까요? loadPostsLoading과 throttle을 적용했는데도 2번씩 실행되는 상황입니다.redux) 작성한 코드) 10,000 자이하만 적을 수 있어서 LOAD_POSTS_REQUEST 관련 코드만 올립니다..!!pages/index.jsimport React, { useEffect } from 'react'; import {useDispatch, useSelector} from 'react-redux'; import AppLayout from '../components/AppLayout'; import PostCard from '../components/PostCard'; import PostForm from '../components/PostForm'; import {LOAD_POSTS_REQUEST} from '../reducers/post'; const Home = () => { const dispatch = useDispatch(); const { me } = useSelector((state) => state.user); const { mainPosts, hasMorePosts, loadPostsLoading } = useSelector((state) => state.post); useEffect(() => { dispatch({ type: LOAD_POSTS_REQUEST, }); }, []); useEffect(() => { function onScroll() { if(window.scrollY + document.documentElement.clientHeight > document.documentElement.scrollHeight-300) { if(hasMorePosts && !loadPostsLoading) { dispatch({ type: LOAD_POSTS_REQUEST, }); } } } window.addEventListener('scroll', onScroll); return () => { window.removeEventListener('scroll', onScroll); }; }, [hasMorePosts, loadPostsLoading]); return ( <AppLayout> {me && <PostForm />} {mainPosts.map((post) => <PostCard key={post.id} post={post} />)} </AppLayout> ); }; export default Home;reducers/post.jsimport shortId from 'shortid'; import {produce} from 'immer'; import faker from 'faker'; export const initialState = { mainPosts:[], imagePaths: [], //게시물 저장 경로 hasMorePosts: true, loadPostsLoading: false, //게시글 로드 완료시 true loadPostsDone: false, loadPostsError: null, } export const generateDummyPost = (number) => Array(number).fill().map(() => ({ id: shortId.generate(), User: { id: shortId.generate(), nickname: faker.name.findName() }, content: faker.lorem.paragraph(), Images: [{ src: 'https://cdn.pixabay.com/photo/2017/07/25/01/22/cat-2536662_1280.jpg' //faker.image.imageUrl(640, 480, true), lorempixel.com 고장나서 임시로 }], Comments: [{ User: { id:shortId.generate(), nickname:faker.name.findName(), }, content:faker.lorem.sentence(), }], })); export const LOAD_POSTS_REQUEST = 'LOAD_POSTS_REQUEST'; export const LOAD_POSTS_SUCCESS = 'LOAD_POSTS_SUCCESS'; export const LOAD_POSTS_FAILURE = 'LOAD_POSTS_FAILURE'; const dummyPost = (data) => ({ id: data.id, content: data.content, User: { id:1, nickname:'해지니', }, Images: [], Comments: [], }); const dummyComment = (data) => ({ id: shortId.generate(), content: data, User: { id: 1, nickname: '제로초' }, }); const reducer = (state = initialState, action) => produce(state, (draft) => { switch(action.type){ case LOAD_POSTS_REQUEST: draft.loadPostsLoading = true; draft.loadPostsDone = false; draft.loadPostsError = null; break; case LOAD_POSTS_SUCCESS: draft.loadPostsLoading = false; draft.loadPostsDone = true; draft.mainPosts = action.data.concat(draft.mainPosts); draft.hasMorePosts = draft.mainPosts.length < 50; break; case LOAD_POSTS_FAILURE: draft.loadPostsLoading = false; draft.loadPostsError = action.error; break; default: break; } }); export default reducer; sagas/post.jsimport { all, fork, takeLatest, put, delay, throttle } from 'redux-saga/effects'; import axios from 'axios'; import shortId from 'shortid'; import { LOAD_POSTS_REQUEST, LOAD_POSTS_SUCCESS, LOAD_POSTS_FAILURE, generateDummyPost, } from '../reducers/post'; function loadPostsAPI(data){ return axios.get('/api/post', data); } function* loadPosts(action) { try{ // const result = yield call(loadPostsAPI, action.data); yield delay(1000); yield put({ type: LOAD_POSTS_SUCCESS, data:generateDummyPost(10) }); } catch(err) { yield put({ type: LOAD_POSTS_FAILURE, data: err.response.data }); } } function* watchLoadPosts(){ yield throttle(5000, LOAD_POSTS_REQUEST, loadPosts); } export default function* postSaga() { yield all([ fork(watchLoadPosts) ]); }사용중인 OS) macOS (Apple M1 Pro)