묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
redux toolkit ssr 질문
계속 똑같은 부분을 질문하고있는데 혹시 똑같은 오류가 발생하고 이 부분 코드는 양이 적고 코드 양이 적어서 오류의 원인을 아는데 용이 할꺼 같아 질문드립니다pages/about.js import React from "react"; import { useSelector } from "react-redux"; import Head from "next/head"; import { Avatar, Card } from "antd"; import AppLayout from "../components/AppLayout"; import wrapper from "../store/configureStore"; import { loadUserInfo } from "../reducers/user"; const Profile = () => { const { userInfo } = useSelector((state) => state.user); return ( <AppLayout> <Head> <title>ZeroCho | NodeBird</title> </Head> {userInfo ? ( <Card actions={[ <div key="twit"> 짹짹 <br /> {userInfo.Posts.length} </div>, <div key="following"> 팔로잉 <br /> {userInfo.Followings.length} </div>, <div key="follower"> 팔로워 <br /> {userInfo.Followers.length} </div>, ]} > <Card.Meta avatar={<Avatar>{userInfo.nickname[0]}</Avatar>} title={userInfo.nickname} description="노드버드 매니아" /> </Card> ) : null} </AppLayout> ); }; export const getStaticProps = wrapper.getStaticProps( (store) => async ({ req }) => { console.log("getStaticProps"); await store.dispatch(loadUserInfo(1)); } ); export default Profile; reducers/user.js export const loadUserInfo = createAsyncThunk( "/user/LoadUserInfo", async (data) => { const response = await axios.get(`/user/${data}`, data); return response.data; } ); const userSlice = createSlice({ name: "user", initialState, reducers: { addPostToMe(draft, action) { // 값을 하나만 전달해서 값이 바로 payload에 저장이된다 // 내가 만든 포스트를 me state에 저장하는 reducer draft.me.Posts.unshift({ id: action.payload }); }, removePostOfMe(draft, action) { draft.me.Posts = draft.me.Posts.filter((v) => v.id !== action.payload); }, }, // 외부에서 action을 만든것은 extraReducers로 가져와서 사용한다 주로 createAsyncThunk로 action을 만들 때 사용한다 extraReducers: (builder) => builder .addCase([HYDRATE], (state, action) => ({ ...state, ...action.payload.user, })) // 다른유저정보 가져오는 리듀서 .addCase(loadUserInfo.pending, (state, action) => { state.loadUserInfoLoading = true; state.loadUserInfoError = null; state.loadUserInfoDone = false; }) .addCase(loadUserInfo.fulfilled, (state, action) => { state.loadUserInfoLoading = false; state.me = action.payload; state.loadUserInfoDone = true; }) .addCase(loadUserInfo.rejected, (state, action) => { state.loadUserInfoLoading = false; state.loadUserInfoError = action.error; }) .addDefaultCase((state) => state), });이런 코드인데 // 다른유저정보 가져오는 리듀서 .addCase(loadUserInfo.pending, (state, action) => { state.loadUserInfoLoading = true; state.loadUserInfoError = null; state.loadUserInfoDone = false; }) .addCase(loadUserInfo.fulfilled, (state, action) => { state.loadUserInfoLoading = false; state.me = action.payload; state.loadUserInfoDone = true; }) .addCase(loadUserInfo.rejected, (state, action) => { state.loadUserInfoLoading = false; state.loadUserInfoError = action.error; })제가 이것저것 하다가 알게된거 action에 이부분을 전부 주석처리하게 되면 에러가 안난다는 겁니다 그래서 결정적으로 initalstate에 있는 변수들을 변경하는 과정이 브라우저의 정보와 서버의 정보를 다르게만드는 일을 하는것 같은데 혹시 의심가시는거 있으신가요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
toolkit을 사용 ssr설정 질문입니다
https://github.com/ZeroCho/react-nodebird/blob/master/toolkit/front/pages/index.js여기 코드를 가져와서 ssr을 설정했습니다front 코드 에러로 Error: Hydration failed because the initial UI does not match what was rendered on the server.Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.이렇게 두개가 나오는데 이걸 어떻게 해결할지 잘 모르겠습니다 initaial UI 에러라길레initialState: { user: { ...userInitialState, me: myInfo, }, post: { ...postInitialState, mainPosts: posts, hasMorePosts: posts.length === 10, }, },주석 처리 되어있는 이부분을 어떻게 해야되는거 같은데 잘 모르겠습니다
-
미해결프로젝트로 배우는 React.js
renderBlogList 함수는 순수함수가 아니어도 괜찮은가요?
React 진영에서 functional component나 hook 등은 순수 함수로 작성하도록 권장되는 것으로 알고 있는데요,renderBlogList 함수는 외부 스코프에 있는 loading, posts값에 의존성을 가지기 때문에 순수함수가 될 수 없는 것으로 보이는데이를 순수함수로 변경하는 것이 더 나은 코드를 작성하는 방법일까요? 아니면 굳이 그렇게 할 필요까지는 없을지 궁금합니다.
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
컴파일 에러
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. const movieId = request.data.result[Math.floor(Math.random() * request.data.results.length)].id; 부분 작성 후 컴파일 시 리액트에서 Cannot read properties of undefined 에러가 발생합니다. 하나가 아니라 여러개 발생하는데 조치방법이 있을까요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
cors 설치하고 404, 500 status 에러가 납니다
npm cors를 설치하고회원가입 버튼을 누르니까 에러가 납니다왜 안되는 건지 알려주세요..
-
미해결프로젝트로 배우는 React.js
페이지네이션 버그 있습니다.
변수 명은 편한대로 변경했습니다.numberOfPageForGroup = currentGroup === lastGroup ? totalPages % limit : limit;처음 알려주신 코드 로직 그대로 사용하면totalPages가 limit으로 나누어 떨어져서 나머지가 0인 경우 버그가 발생합니다. const numberOfPageForGroup = currentGroup === lastGroup && totalPages % limit !== 0 ? totalPages % limit : limit;나누어 떨어지는 경우도 처리해줘야 정상 작동합니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
프로젝트에 사용할 상태와 로직 관리 라이브러리 훅 사용 질문입니다.
로그인 및 인증,인가(세션,jwt둘다 사용), 게시판(이미지포함), 댓글, 소켓채팅 정도의 기능을 구현하여 테스트 코드와 docker로 띄워서 CI/CD까지 구현하려고 합니다.상태랑 로직 관리를 useReducer, React Context API, React Query, redux, graphql 정도로 생각하고 있는데 어떤걸로 하는게 좋을까요?!
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
프로필 페이지 세로고침 에러
프로필페이지 에서 세로고침을 할때 로그인이 풀리면서 로그인 정보가 사라지면서 에러가 발생하는 현상이 있었습니다const Profile = () => { const { me } = useSelector((state) => state.user); const dispatch = useDispatch(); useEffect(() => { if (!(me && me.id)) { Router.push("/"); } }, [me && me.id]); useEffect(() => { dispatch(loadFollowers()); dispatch(loadFollowings()); }, []); return ( <> <Head> <title>프로필 | NodeBird</title> </Head> <AppLayout> <NicknameEditForm /> <FollowList header="팔로잉 목록" data={me?.Followings} /> <FollowList header="팔로워 목록" data={me?.Followers} /> </AppLayout> </> ); };그런데 이해가 안되는점은 Router.push로 me에 대한 정보가 없으면 루트 페이지로 넘어가게 만들어두었는데도 로그인 정보가 없다고 에러가 발생하고 그래서 로그인 정보를 가져오는 loadMyInfo를 사용해도 계속 에러가 발생한다는 점입니다.이부분이 일단 첫번째로 이해가 안되는 점이고아래 질문자님들이 질문하신 내용으로 me?.Foolowings로 일단 해결하고 넘어갔습니다그런데 또 프로필 페이지에서 세로고침을 해보니까 이번에도 me에 대한 정보가 없다고 나옵니다me에 대한 정보가 없어서 발생하는 에러인데 팔로워에 대한 정보를 불러오는 리듀서에서 에러가 발생합니다 하지만 사진에 state 정보를 보시면 me에 정보가 들어있습니다. 아마 me 정보를 갱신하기 이전에 발생한 action에 대한 에러인거 같은데 어떻게 해결하면 좋을까요?
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
auth 미들웨어 관련 질문
const jwt = require("jsonwebtoken"); const User = require("../models/User"); let auth = async (req, res, next) => { // 토큰을 request headers에서 가져오기 const authHeader = req.headers["authorization"]; // Bearer ooerkogkeorkgoek.erogkoerkog.eorgkoerkgoerkgokg const token = authHeader && authHeader.split(" ")[1]; if (token === null) return res.sendStatus(401); try { // 토큰이 유효한 토큰인지 확인 const decode = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findOne({ "_id": decode.userId }); if (!user) { return res.status(400).send("없는 유저입니다."); } req.user = user; next(); } catch (error) { next(error); } }; module.exports = auth;기존에 "_id"로 되어있을 때, C:\Users\zink8060\Desktop\fullstack-app\back\node_modules\express\lib\router\route.js:211 throw new Error(msg); ^Error: Route.get() requires a callback function but got a [object Object] at Route.<computed> [as get] (C:\Users\zink8060\Desktop\fullstack-app\back\node_modules\express\lib\router\route.js:211:15) at proto.<computed> [as get] (C:\Users\zink8060\Desktop\fullstack-app\back\node_modules\express\lib\router\index.js:521:19) at Object.<anonymous> (C:\Users\zink8060\Desktop\fullstack-app\back\src\routes\users.js:7:8) at Module._compile (node:internal/modules/cjs/loader:1246:14) at Module._extensions..js (node:internal/modules/cjs/loader:1300:10) at Module.load (node:internal/modules/cjs/loader:1103:32) at Module._load (node:internal/modules/cjs/loader:942:12) at Module.require (node:internal/modules/cjs/loader:1127:19) at require (node:internal/modules/helpers:112:18) at Object.<anonymous> (C:\Users\zink8060\Desktop\fullstack-app\back\src\index.js:33:19)해당 오류가 있었는데,해당 부분을 _id로 바꿨더니 정상적으로 서버가 동작합니다.const jwt = require("jsonwebtoken"); const User = require("../models/User"); let auth = async (req, res, next) => { // 토큰을 request headers에서 가져오기 const authHeader = req.headers["authorization"]; // Bearer ooerkogkeorkgoek.erogkoerkog.eorgkoerkgoerkgokg const token = authHeader && authHeader.split(" ")[1]; if (token === null) return res.sendStatus(401); try { // 토큰이 유효한 토큰인지 확인 const decode = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findOne({ _id: decode.userId }); if (!user) { return res.status(400).send("없는 유저입니다."); } req.user = user; next(); } catch (error) { next(error); } }; module.exports = auth;하지만 강사님의 코드에는 "_id"로 되어있는데, 버전문제일까요? 아니면 다른 문제가 있을까요?
-
미해결실무 중심! FE 입문자를 위한 React
swr과 recoil을 같이 쓰려면 어떻게 쓰면 될까요?
안녕하세요. 유익한 강의 감사합니다. 강의를 다 듣고나니 recoil 과 swr을 같이 쓰고 싶다는 생각이 들어서 redux를 썼던 admin 페이지를 swr과 recoil 조합으로 만들어보다가 막혀서 질문드립니다.. pages/ListPage.js에서 const { data, error, mutate } = useSWR( "/surveys?_sort_id&_order=desc", fetcher, ); const [survey, setSurvey] = useCurrentQuestion(); // recoil setSurvey(data);이렇게 swr로 불러온 데이터를 set으로 넣어주고 다른 페이지에서 recoil로 데이터를 불러서 써도 되는지 궁금합니다. 아니면 커스텀 훅에서 swr을 사용해도 괜찮을까요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
스크롤 시 dispatch 중복 요청 에러 질문 있습니다.
홈페이지에서 스크롤 시 콜백함수가 실행되는 과정에서 LOAD_POSTS_REQUEST dispatch 요청을 두 번 보내는 상황이 발생하였는데 해결하지 못해서 올립니다./pages/index.jsconst Home = () => { const dispatch = useDispatch(); const { me } = useSelector((state) => state.user); const { mainPosts, hasMorePosts, loadPostLoading, retweetError } = useSelector((state) => state.post); useEffect(() => { if (retweetError) { alert(retweetError); } }, [retweetError]); useEffect(() => { dispatch({ type: LOAD_MY_INFO_REQUEST, }); dispatch({ type: LOAD_POSTS_REQUEST, }); }, []); useEffect(() => { function onScroll() { if ( window.scrollY + document.documentElement.clientHeight > document.documentElement.scrollHeight - 300 ) { if (hasMorePosts && !loadPostLoading) { console.log('스크롤 패칭'); const lastId = mainPosts[mainPosts.length - 1]?.id; console.log('lastId', lastId); dispatch({ type: LOAD_POSTS_REQUEST, lastId, }); } } } window.addEventListener('scroll', onScroll); return () => { window.removeEventListener('scroll', onScroll); }; }, [hasMorePosts, loadPostLoading, mainPosts]); return ( <AppLayout> {me && <PostForm />} {mainPosts.map((post) => ( <PostCard key={post.id} post={post} /> ))} </AppLayout> ); };sagas/post.jsfunction loadPostsAPI(lastId) { return axios.get(`/posts?lastId=${lastId || 0}`); } function* loadPosts(action) { try { const result = yield call(loadPostsAPI, action.data); yield put({ type: LOAD_POSTS_SUCCESS, data: result.data, }); } catch (err) { yield put({ type: LOAD_POSTS_FAILURE, error: err.response.data, }); } } function* watchLoadPosts() { yield throttle(5000, LOAD_POSTS_REQUEST, loadPosts); }reducers/post.jscase LOAD_POSTS_REQUEST: draft.loadPostLoading = true; draft.loadPostDone = false; draft.loadPostError = null; break; case LOAD_POSTS_SUCCESS: draft.loadPostLoading = false; draft.loadPostDone = true; draft.mainPosts = draft.mainPosts.concat(action.data); draft.hasMorePosts = action.data.length === 10; break; case LOAD_POSTS_FAILURE: draft.loadPostLoading = false; draft.loadPostError = action.error; break;첫 페이지 로딩 후에 스크롤 시 onScroll 함수의 '스크롤 패칭'이 콘솔에 두 번 찍히고 LOAD_POSTS_REQUEST 요청이 두 번 가는 것을 확인했고 처음 포스트들을 불러온 이후에 lastId가 0으로 요청이 보내져서 mainPosts에 중복된 게시물이 쌓이는 문제가 있습니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
Object is not iterable
npm run dev를 하면 Object is not iterabled 이런 에러가 뜹니다제 코드는import React, { useState, useCallback } from "react"; import { Button, Form, Input } from "antd"; import Link from "next/link"; import styled from "styled-components"; import useInput from "../hooks/useInput"; const ButtonWrapper = styled.div` margin-top: 10px; `; const FormWrapper = styled(Form)` padding: 10px; `; const LoginForm = ({ setIsLoggedIn }) => { const [id, onChangeId] = useInput(""); const [password, setPassword] = useInput(""); const onSubmitForm = useCallback(() => { console.log(id, password); setIsLoggedIn(true); }, []); return ( <FormWrapper onFinish={onSubmitForm}> <div> <label htmlFor="user-id">아이디</label> <br /> <Input name="user-id" value={id} onChange={onChangeId} required /> </div> <div> <label htmlFor="user-id">비밀번호</label> <br /> <Input name="user-id" value={password} onChange={onChangePassword} required /> </div> <ButtonWrapper> <Button type="primary" htmlType="submit" loading={false}> 로그인 </Button> <Link href="/signup"> <a> <Button>회원가입</Button> </a> </Link> </ButtonWrapper> </FormWrapper> ); }; export default LoginForm; 이 부분이 문제라곤 하는데 어떻게 하나요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
페이지 이동시에 너무 느림
넥스트 서버사이드렌더링 까지 다한상태인데 getStaticProps는 정말 빨리 넘어갑니다 하지만 getServerSideProps으로 만든 페이지는 정말 3초? 이상 걸립니다. 서버도 다 한국으로 시작했고 GCP 쓰고 있습니다서버속도 문제가 아니라면 속도를 줄일수있는방법이 머가있을까요.. ㅜㅜbuild 시에 페이지 용량도 높지 않습니다. 정적페이지랑 차이도 별루 없구요 ㅜㅠ2.back 에서 데이터를 가져올 때 시간이 많이 걸리는거 같은데 페이지 이동이라도 빠르게 진행하고 그다음 데이터를 불러오는 방법을 어떻게 깔삼하게 구현할 수 있을까요..
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
find로 댓글을 가져오는 부분이 이상합니다
console.log로 action과 post를 찍어봤는데 post의 값이 이상합니다redux dev tools도 확인해보면 제가 지금 넣은 데이터의 형식이 content만 들어가 있습니다 어떻게 해야하나요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
Button is not defined
프로필 탭 들어갈 시 Button is not defined 이라는 오류가 뜹니다 제 코드는 import React from "react"; import PropTypes from "prop-types"; import { List } from "antd"; import Item from "antd/lib/list/Item"; import { StopOutlined } from "@ant-design/icons"; import { isStyledComponent, keyframes } from "styled-components"; const FollowList = ({ header, data }) => { return ( <List style={{ marginBottom: 20 }} grid={{ gutter: 4, xs: 2, md: 3 }} size="small" header={<div>{header}</div>} loadMore={ <div style={{ textAlign: "center", margin: "10px 0" }}> <Button>더 보기</Button> </div> } bordered dataSource={data} renderItem={(Item) => ( <List.Item style={{ marginTop: 20 }}> <Card actions={[<StopOutlined key="stop" />]}> <Card.Meta description={Item.Nickname} /> </Card> </List.Item> )} /> ); }; FollowList.propTypes = { header: PropTypes.string.isRequired, data: PropTypes.array.isRequired, }; export default FollowList; 입니다 무엇이 문제 일까요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
try catch문이 있는데 if문으로 에러처리를 따로 하는 이
router.get("/", async (req, res, next) => { try { if (req.user) { // findOne에서 에러가 생기는 거는 try catch문으로 처리가 안된 const user = await User.findOne({ where: { id: req.user.id }, }); res.status(200).json(user); } else { res.status(200).json(null); } } catch (error) { console.error(error); next(error); } });이부분에서 아직 로그인을 하지 않아서 유저 정보가 없을때 User.findOne에서 에러가 나기 때문에 if문으로 감싸서 아직 유저정보가 없을 때를 예외 처리 해주셨는데 어차피 User.findOne에서 에러가 나면 catch문으로 이동해서 에러가 처리가 되는데 굳이 if else로 예외 처리 하신 이유가 있나요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
POST http://localhost:3065/post 500 (Internal Server Error) 500에러 질문 입니다
redux toolkit을 이용해서 코딩을 하고 있고 credentials까지 강의 나와있는대로 다 작성을 한 상태입니다post action creator는 이렇게 작성하였고export const addPost = createAsyncThunk( "/post", async (data, { fulfillWithValue, rejectWithValue }) => { try { console.log(data); const response = await axios.post("/post", data); console.log(response.data); return fulfillWithValue(response.data); } catch (error) { throw rejectWithValue(error.response); } } );에러메시지는 POST http://localhost:3065/post 500 (Internal Server Error)redux dev tools에 rejected 요청으로 온 여러 정보가 있는데 그중에 뭐가 필요한 정보인지 몰라서 제로초님이 필요하신 정보를 얘기해주시면 추가적으로 추가 하겠습니다status(pin):500statusText(pin):"Internal Server Error"일단 이 두개가 상태 메시지입니다
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
Fast Refresh Warning
터미널에 다음과 같은 경고가 뜹니다.warn - Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works TypeError: Failed to fetch at webpack_require.hmrM (http://localhost:3000/_next/static/chunks/webpack.js?ts=1690436755699:1201:20)작성한 코드AppLayout.jsimport { Menu } from "antd"; import Link from "next/link"; import PropTypes from "prop-types"; import React from "react"; const items = [ { label: ( <Link href="/"> <a>홈</a> </Link> ), key: "home", }, { label: <Link href="/profile">프로필</Link>, key: "profile", }, { label: ( <Link href="/signup"> <a>회원가입</a> </Link> ), key: "signup", }, ]; function AppLayout({ children }) { return ( <div> <Menu mode="horizontal" items={items}></Menu> {children} </div> ); } AppLayout.propTypes = { children: PropTypes.node.isRequired, }; export default AppLayout; index.jsimport React from "react"; import AppLayout from "../components/AppLayout"; function Home() { return ( <AppLayout> <div>Hello, Next!</div> </AppLayout> ); } export default Home; Fast Refresh 관련 문서를 보고 새로 고침도 해보고, 캐시도 지워보고, 익명 함수를 기명 함수로 바꿔보았지만 소용이 없었습니다.npm run dev를 실행하고 localhost에 접속할 때마다 보입니다.웹페이지 우측 하단에 vercel mark 같은 것이 잠시 깜빡이는데 그 때에도 fast refresh 관련 warnning이 뜹니다.next.js 12 버전, antd 5버전을 사용 중이며 질문 시점에 강의는 Section1의 1강 수강 했습니다.
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
서로 다른 팔로우 버튼을 빠르게 눌렀을때 둘다 팔로우 성공시키는 방법?
(클릭한 버튼만 loading이 되게 해놓은 상태에서)서로 다른 두개의 팔로우 버튼을 빠르게(1초안에) 클릭했을때요청이 두번가는데 두번째거만 성공하는 이유는takeLatest를 사용해서 그런것이 맞나요?둘다 성공시키기 위해 takeEvery를 사용했는데그래도 될까요?function* watchFollow() { yield takeEvery(FOLLOW_REQUEST, follow); } function* watchUnfollow() { yield takeEvery(UNFOLLOW_REQUEST, unfollow); } 그리고 혹시 takeLatest를 써도 서버에 여러개의 요청이 가니까 서버에서 여러 요청을 모두 성공하게끔 처리가 될까요?
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
handleSumbit부분 redux로 빼지 않은 이유
UploadProductPage의handleSumbit 부분을 dispatch로 하지 않고바로 페이지안에서 작성한 이유가 따로 있는건가요??