오류 어디 봐야하나요??


index.js:43 {mainPosts.map((post) => ( 이부분입니다
_App.js:14 <Component /> 여기인데 원인을 모르겠네요
pages/_App.js
import React from 'react';
import 'antd/dist/antd.css';
import Head from 'next/head';
import PropTypes from 'prop-types';
import wrapper from '../store/configureStore';
const NodeBird = ({Component}) => (
<>
<Head>
<meta charSet='utf-8' />
<title>NodeBird</title>
</Head>
<Component />
</>
);
NodeBird.propTypes = {
Component: PropTypes.elementType.isRequired
};
export default wrapper.withRedux(NodeBird);pages/index
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import AppLayout from '../components/AppLayout';
import PostForm from '../components/PostForm';
import PostCard from '../components/PostCard';
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() {
// scrollY: 얼마나 내렸는지, clientHeight: 화면에 보이는 길이, scrollHeight: 총 길이
console.log(window.scrollY,
document.documentElement.clientHeight,
document.documentElement.scrollHeight);
if(window.scrollY + document.documentElement.clientHeight > document.documentElement.scrollHeight - 300) {
if(hasMorePosts && !loadPostsLoading) {
dispatch({
type: LOAD_POSTS_REQUEST,
data: mainPosts[mainPosts.length - 1].id,
});
}
}
}
window.addEventListener('scroll', onScroll);
return() => {
window.removeEventListener('scroll', onScroll);
};
}, [mainPosts, hasMorePosts, loadPostsLoading]);
return (
<AppLayout>
{me && <PostForm />}
{mainPosts.map((post) => (
<PostCard key={post.id} post={post} />
))}
</AppLayout>
);
};
export default Home;
github 코드랑 강의코드랑 다른거 같아요..
github 보면서 index쪽이랑 _app쪽 코드 바꿔봤는데 안되네요
어디쪽 문제일까요 ??
그리고 faker 이렇게 뜨는데 안되는거 같아요
reducers/post.js


faker 강의 들을때 이부분 에러 나서 주석처리하니까 정상작동 됐어요
faker 4버전,5버전 둘다 해봐도 안됐어요 지금은 4버전 설치되있어요
근데 첫번째 에러 해결해야 faker쪽 에러 확인 가능할듯 합니다
답변 1
0
mainPosts가 배열이 아니라서 문제인 것입니다. mainPosts를 건드는 쪽을 집중적으로 보셔야 하고요. 리듀서 쪽일 겁니다. 그리고 faker 관련 이슈일 수도 있습니다.
0
reducers쪽 코드 보면서 비교해도 똑같은거 같아요ㅠ
github에 reducers폴더 복붙해도 똑같은 에러 뜨고..
여기가 아닌거 같아요..
index.js
import { HYDRATE } from 'next-redux-wrapper';
import { combineReducers } from "redux";
import user from './user';
import post from './post';
// 다른 State
// (이전상태, 액션) => 다음상태
const rootReducer = combineReducers({
index: (state = {}, action) => {
switch(action.type) {
case HYDRATE:
console.log('HYDRATE', action);
return {
...state,
...action.payload
};
default:
return state;
}
},
user,
post,
});
export default rootReducer;
post.js
import shortId from "shortid";
import produce from "immer";
// import faker from 'faker';
export const initialState = {
mainPosts: [],
imagePaths: [],
hasMorePosts: true,
loadPostsLoading: false,
loadPostsDone: false,
loadPostsError: null,
addPostLoading: false,
addPostDone: false,
addPostError: null,
removePostLoading: false,
removePostDone: false,
removePostError: null,
addCommentLoading: false,
addCommentDone: false,
addCommentError: null
};
// export const generateDummyPost = (number) => Array(number).fill().map(() => ({
// id: shortId.generate(),
// User: {
// id: shortId.generate(),
// nickname: faker.name.fineName()
// },
// content: faker.lorem.paragraph,
// Images: [{
// src: faker.image.imageUrl()
// }],
// 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';
export const ADD_POST_REQUEST = 'ADD_POST_REQUEST';
export const ADD_POST_SUCCESS = 'ADD_POST_SUCCESS';
export const ADD_POST_FAILURE = 'ADD_POST_FAILURE';
export const REMOVE_POST_REQUEST = 'REMOVE_POST_REQUEST';
export const REMOVE_POST_SUCCESS = 'REMOVE_POST_SUCCESS';
export const REMOVE_POST_FAILURE = 'REMOVE_POST_FAILURE';
export const ADD_COMMENT_REQUEST = 'ADD_COMMENT_REQUEST';
export const ADD_COMMENT_SUCCESS = 'ADD_COMMENT_SUCCESS';
export const ADD_COMMENT_FAILURE = 'ADD_COMMENT_FAILURE';
export const addPost = (data) => ({
type: ADD_POST_REQUEST,
data
});
export const addComment = (data) => ({
type: ADD_COMMENT_REQUEST,
data
});
const dummyPost = (data) => ({
id: data.id,
content: data.content,
User: {
id: 1,
nickname: 'ABC'
},
Images: [],
Comments: []
});
const dummyComment = (data) => ({
id: shortId.generate(),
content: data,
User: {
id: 1,
nickname: 'ABC'
},
});
// 이전 상태를 액션을 통해 다음 상태로 만들어내는 함수(불변성은 지키면서)
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;
case ADD_POST_REQUEST:
draft.addPostLoading = true;
draft.addPostDone = false;
draft.addPostError = null;
break;
case ADD_POST_SUCCESS:
draft.addPostLoading = false;
draft.addPostDone = true;
draft.mainPosts.unshift(dummyPost(action.data));
break;
case ADD_POST_FAILURE:
draft.addPostLoading = false;
draft.addPostError = action.error;
break;
case REMOVE_POST_REQUEST:
draft.removePostLoading = true;
draft.removePostDone = false;
draft.removePostError = null;
break;
case REMOVE_POST_SUCCESS:
draft.removePostLoading = false;
draft.removePostDone = true;
draft.mainPosts = draft.mainPosts.filter((v) => v.id !== action.data);
break;
case REMOVE_POST_FAILURE:
draft.removePostLoading = false;
draft.removePostError = action.error;
break;
case ADD_COMMENT_REQUEST:
draft.addCommentLoading = true;
draft.addCommentDone = false;
draft.addCommentError = null;
break;
case ADD_COMMENT_SUCCESS:{
const post = draft.mainPosts.find((v) => v.id === action.data.postId);
post.Comments.unshift(dummyComment(action.data.content));
draft.addCommentLoading = false;
draft.addCommentDone = true;
break;
// const postIndex = state.mainPosts.findIndex((v) => v.id === action.data.postId);
// const post = { ...state.mainPosts[postIndex] };
// post.Comments = [dummyComment(action.data.content), ...post.Comments];
// const mainPosts = [...state.mainPosts];
// mainPosts[postIndex] = post;
// return {
// ...state,
// addCommentLoading: false,
// addCommentDone: true,
// };
};
case ADD_COMMENT_FAILURE:
draft.addCommentLoading = false,
draft.addCommentError = action.error
break;
default:
break;
}
});
export default reducer;
user.js
import produce from "immer";
export const initialState = {
followLoading: false, // 팔로우 시도중
followDone: false,
followError: null,
unfollowLoading: false, // 언팔로우 시도중
unfollowDone: false,
unfollowError: null,
logInLoading: false, // 로그인 시도중
logInDone: false,
logInError: null,
logOutLoading: false, // 로그아웃 시도중
logOutDone: false,
logOutError: null,
signUpLoading: false, // 회원가입 시도중
signUpDone: false,
signUpError: null,
changeNicknameLoading: false, // 닉네임 변경 시도중
changeNicknameDone: false,
changeNicknameError: null,
me: null,
signUpData: {},
loginData: {}
}
const dummyUser = (data) => ({
...data,
nickname: 'G',
id: 1,
Posts: [{id: 1}],
Followings: [{nickname: 'R'}, {nickname: 'L'}, {nickname: 'N'}],
Followers: [{nickname: 'R'}, {nickname: 'L'}, {nickname: 'N'}],
});
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 loginRequestAction = (data) => ({
type: LOG_IN_REQUEST,
data
});
export const logoutRequestAction = () => ({
type: LOG_OUT_REQUEST
});
// return(생략) produce
const reducer = (state = initialState, action) => produce(state, (draft) => {
switch(action.type) {
case FOLLOW_REQUEST:
draft.followLoading = true;
draft.followError = null;
draft.followDone = false;
break;
case FOLLOW_SUCCESS:
draft.followLoading = false;
draft.me.Followings.push({ id: action.data });
draft.followDone = true;
break;
case FOLLOW_FAILURE:
draft.followLoading = false;
draft.followError = action.error;
break;
case UNFOLLOW_REQUEST:
draft.unfollowLoading = true;
draft.unfollowError = null;
draft.unfollowDone = false;
break;
case UNFOLLOW_SUCCESS:
draft.unfollowLoading = false;
draft.me.Followings = draft.me.Followings.filter((v) => v.id !== action.data);
draft.unfollowDone = true;
break;
case UNFOLLOW_FAILURE:
draft.unfollowLoading = false;
draft.unfollowError = action.error;
break;
case LOG_IN_REQUEST:
draft.logInLoading = true;
draft.logInError = null;
draft.logInDone = false;
break;
case LOG_IN_SUCCESS:
draft.logInLoading = false;
draft.me = dummyUser(action.data);
draft.logInDone = true;
break;
case LOG_IN_FAILURE:
draft.logInLoading = false;
draft.logInError = action.error;
break;
case LOG_OUT_REQUEST:
draft.logOutLoading = true;
draft.logOutError = null;
draft.logOutDone = false;
break;
case LOG_OUT_SUCCESS:
draft.logOutLoading = false;
draft.logOutDone = true;
draft.me = null;
break;
case LOG_OUT_FAILURE:
draft.logOutLoading = false;
draft.logOutError = action.error;
break;
case SIGN_UP_REQUEST:
draft.signUpLoading = true;
draft.signUpError = null;
draft.signUpDone = false;
break;
case SIGN_UP_SUCCESS:
draft.signUpLoading = false;
draft.signUpDone = true;
break;
case SIGN_UP_FAILURE:
draft.signUpLoading = false;
draft.signUpError = action.error
break;
case CHANGE_NICKNAME_REQUEST:
draft.changeNicknameLoading = true;
draft.changeNicknameError = null;
draft.changeNicknameDone = false;
break;
case CHANGE_NICKNAME_SUCCESS:
draft.changeNicknameLoading = false;
draft.changeNicknameDone = true;
break;
case CHANGE_NICKNAME_FAILURE:
draft.changeNicknameLoading = false;
draft.changeNicknameError = action.error;
break;
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;
0

redux-devtools 이렇게 뜹니다
pages/index.js

여기 주석 처리하면 정상작동 되는데 보니까 삭제 기능이 사라져 있네요..
이 부분은 어디로 가야하나요 ㅠㅠ
saga/post.js , reducers/post.js 안에 REMOVE_POST 다 확인했는데 왜이러죠
0
문제를 하나씩 해결하세요. mainPosts 문제부터 해결 후에 삭제 쪽을 보시고요. 혼자만 보지 마시고 코드를 올려주세요.
다음 영상 보시는 게 좋을 것 같습니다.
0
지금 보니까 LOAD_POSTS_SUCCESS의 data가 배열이 아니라 문자열로 들어옵니다. 그래서 reducer에서도 배열이 아니라 문자열이 되는 것이고요. LOAD_POSTS_SUCCESS를 하는 곳을 봐야겠죠.
0
찾았어요
sagas/post.js 안에 loadPosts
function* loadPosts(action) {
try {
// const result = yield call(loadPostAPI, 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
});
}
}
reducer/post.js 안에 generateDummyPost
export const generateDummyPost = (number) => Array(number).fill().map(() => ({
id: shortId.generate(),
User: {
id: shortId.generate(),
nickname: faker.name.fineName()
},
content: faker.lorem.paragraph,
Images: [{
src: faker.image.imageUrl()
}],
Comments: [{
User: {
id: shortId.generate(),
nickname: faker.name.findName()
},
content: faker.lorem.sentence()
}],
}));data에 다른거 들어가 있어서 고쳤는데 generateDummyPost 이거는 faker인데
faker 위에 본문 보시면 4,5버전 다 저렇게 뜨면서 안되서 그런지 무한 로딩 걸리네요...


0
catch (err) {
console.error(err);
yield put({
type: LOAD_POSTS_FAILURE,
data: err.response.data
});에러 안뜨는거 같아요
vsCode에는 에러 안뜹니다
콘솔 오류

넥스트 버젼 질문
0
90
2
로그인시 401 Unauthorized 오류가 뜹니다
0
104
1
무한 스크롤 중 스크롤 튐 현상
0
197
1
특정 페이지 접근을 막고 싶을 때
0
116
2
createGlobalStyle의 위치와 영향범위
0
103
2
인라인 스타일 리렌더링 관련
0
98
2
vsc 에서 npm init 설치시 오류
0
159
2
nextjs 15버전 사용 가능할까요?
0
166
1
화면 새로고침 문의
0
129
1
RTK에서 draft, state 차이가 있나요?
0
164
2
Next 14 사용해도 될까요?
0
455
1
next, node 버전 / 폴더 구조 질문 드립니다.
0
359
1
url 오류 질문있습니다
0
218
1
ssh xxxxx로 우분투에 들어가려니까 port 22: Connection timed out
0
391
1
sudo certbot --nginx 에러
0
1295
2
Minified React error 콘솔에러 (hydrate)
0
481
1
카카오 공유했을 때 이전에 작성했던 글이 나오는 버그
0
257
1
프론트서버 배포 후 EADDRINUSE에러 발생
0
341
1
npm run build 에러
0
526
1
front 서버 npm run build 중에 발생한 에러들
0
399
1
서버 실행하고 브라우저로 들어갔을때 404에러
0
351
2
css 서버사이드 랜더링이 적용되지 않아서 문의 드립니다.
0
291
1
팔로워 3명씩 불러오고 데이터 합쳐주는걸로 바꾸고 서버요청을 무한으로하고있습니다.
0
250
2
해시태그 검색에서 throttle에 관해 질문있습니다.
0
207
1






