묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
getStaticProps, getServerSideProps 관련해서 질문드립니다.
안녕하세요 zerocho님. 항상 친절하게 답변주셔서 감사합니다. 몇가지 질문이 있습니다. 1. getServerSideProps에서는 브라우저에서 쿠키를 들고 next.js 서버로 오기 때문에 cookie를 가지고 올 수 있다고 이해했는데 getStaticProps는 빌드 시에 실행되기 때문에 cookie를 들고있지 못한걸로 이해했는데 맞나요? 만약 그렇다면 getStaticProps에서 사용하는 API는 인증이 필요하지 않은 API만 사용해야하나요? 2. getServerSideProps는 SSR이라 이를 이용하게되면 화면이 전체 깜빡임이 일어날거라고 생각했는데 실제로는 일어나지 않더라구요. 혹시 이유를 알고 계신지 궁금합니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
redux와 react-query 설정
다른 질문 들도 보다가 궁금한 점이 생겨 여쭤봅니다. 프로젝트에서 내에서 상태관리를 redux로 하고 server에서 데이터 패칭하는 부분을 (공부해 보니 server state라고 부르더군요) react-query(또는 swr)로 사용하려는 경우 설정을 어떻게 해야하나 궁금해서 검색해봤는데 마땅한 자료가 없어서 질문드려요 CRA기준으로 index.js에 import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; import reducer from "./reducer"; import { Provider } from "react-redux"; import { configureStore } from "@reduxjs/toolkit"; import { Global } from "@emotion/react"; import { GlobalStyle } from "./index.style"; import { QueryClientProvider, QueryClient } from "react-query"; const store = configureStore({ reducer }); const queryClient = new QueryClient(); ReactDOM.render( <Provider store={store}> <QueryClientProvider client={queryClient}> <App /> <Global styles={GlobalStyle} /> </QueryClientProvider> </Provider>, document.getElementById("root") ); 이런식으로 사용해서 reducer 함수 정의하고 각 컴포넌트에서 queryClient를 import해서 사용하는 건가요? 제로초님 강의 들으면서 react-query를 이제 막 공부하고 있는데 react-query가 내부적으로 contextAPI 사용한다고 알고있는데 redux랑 contextAPI를 같이 쓴다는게 정확히 감이 안잡히네요 제가 잘못알고 있는 부분이나 공부해야할 키워드를 알려주시면 감사하겠습니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
useQuery refetch
제로초님 제가 react-query useQuery Hook을 사용하여 데이터를 받아왔습니다. 이 데이터 값들을 버튼 onClick 함수를 만들어서 버튼을 클릭할 때마다, useQuery api 요청을 콜을 해 주고 싶습니다. 그래서 찾아보니 useQuery refetch 를 알게되었고, refetch 함수를 onClick 함수에 넣어주었는데, 동작을 하지 않네요 ㅠㅠ. useQuery api를 버튼을 클릭할 떄 마다 api call 을 해주고 싶은데 어떻게 해줘야 할까요...
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
실무에서도 styled component를 해당 컴포넌트에 다 작성하나요?
antd같은 ui 컴포넌트를 사용안하면 한 컴포넌트 안에서 styled component가 차지하는 코드량이 상당히 많을 것 같은데 실무에서도 styled component의 코드길이에 상관없이 해당 컴포넌트에 다 적는지 아니면 따로 폴더에 분리해서 import하는지 궁금합니다.
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
"더미데이터와 포스트폼 만들기" 강의순서 관련 코드 작성 뒤, 로그인에서 게시판으로 넘어가지 않는 문제로 질문 드립니다!
안녕하세요. 제로초님의 강의에 큰 도움을 받고 있음에 감사의 말씀을 드립니다. 여러 검색결과도, 질문답변도, 해당강의 반복재생으로 찾아보았으나 해결치 못한 부분이 있어 이렇게 직접 질문을 하게 됐네요! [ 마주한 문제점 & 상황 ] 은 다음과 같습니다. 1. (이전상황) 로그인폼(Id, Pwd)에 텍스트를 입력해 "로그인" 버튼을 누르면 정상적으로 로그인이 됐고, Redux 역시 정상작동해 개발자도구에서 확인이 가능했습니다. 2. (현재상황) 섹션3(Redux) "더미데이터와 포스트폼 만들기" 강의를 들으며 문제에 마주했습니다. 3. (더미데이터와 포스트폼 만들기 강의 후) 잘 넘어가던 로그인 화면에서 데이터는 넘어가 콘솔에 찍히지만, 화면 페이지는 게시판으로 넘어가지 않는 상황에 직면했습니다. [ 콘솔에 찍히는 Error ] 는 다음과 같습니다. [정상적으로 넘어가는 로그인 데이터] -> 그러나 로그인이 되지 않고 화면이 넘어가질 않습니다! [ 소스코드 ] 1. package.json { "name": "react-nodebird-front", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "next -p 3060", "build": "next build" }, "author": "jj", "license": "ISC", "dependencies": { "@ant-design/icons": "^4.7.0", "antd": "^4.19.0", "next": "^9.5.5", "next-redux-wrapper": "^6.0.2", "prop-types": "^15.8.1", "react": "^16.14.0", "react-dom": "^16.14.0", "react-redux": "^7.2.8", "redux": "^4.1.2", "redux-devtools-extension": "^2.13.9", "styled-components": "^5.3.3" }, "devDependencies": { "eslint": "^8.10.0", "eslint-plugin-hooks": "^0.4.2", "eslint-plugin-import": "^2.25.4", "eslint-plugin-react": "^7.29.3" } } 2. LoginForm.js 파일 import React, { useState, useCallback, useMemo } from 'react'; import { Form, Input, Button } from 'antd'; import Link from 'next/link'; import styled from 'styled-components'; import { useDispatch, useSelector } from 'react-redux'; import useInput from "../hooks/useInput"; import { loginAction } from '../reducers/user'; const ButtonWrapper = styled.div ` margin-top: 10px; `; const FormWrapper = styled(Form) ` padding: 10px; `; const LoginForm = ({ setIsLoggedIn }) => { const dispatch = useDispatch(); const [id, onChangeId] = useInput(''); const [password, onChangePassword] = useInput(''); const onSubmitForm = useCallback(() => { console.log(id, password); dispatch(loginAction({id, password})); }, [id, password]); 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-password">비밀번호</label> <br /> <Input name="user-password" type="password" 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; 3. index.js import React from 'react'; import { useSelector } from "react-redux"; import AppLayout from "../components/AppLayout"; import PostForm from '../components/PostForm'; import PostCard from '../components/PostCard'; const Home = () => { const { isLoggedIn } = useSelector((state) => state.user); const { mainPosts } = useSelector((state) => state.post); return ( <AppLayout> {isLoggedIn && <PostForm /> } {mainPosts.map((post) => <PostCard key={post.id} post={post} />)} </AppLayout> ); } export default Home; 4. configureStore.js import { createWrapper } from 'next-redux-wrapper'; import { applyMiddleware, compose, createStore } from 'redux'; import { composeWithDevTools } from 'redux-devtools-extension'; import reducer from '../reducers'; const configureStore = () => { const middlewares = []; const enhancer = process.env.NODE_ENV === 'production' ? compose(applyMiddleware(...middlewares)) : composeWithDevTools(applyMiddleware(...middlewares)); const store = createStore(reducer, enhancer); return store; }; const wrapper = createWrapper(configureStore, { debug: process.env.NODE_ENV === 'development', }); export default wrapper; 5. post.js // [ initialState ] export const initialState = { mainPosts: [{ id: 1, User: { id: 1, nickname: 'jj', }, content: '첫 번째 게시글 #해시태그 #익스프레스', Images: [{ src: 'https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAxNjExMjFfMjM2%2FMDAxNDc5NjY5MjEyOTEz.13R8uiaA0T8rJnLPJICAib4oVtrAzA424jbDMC9a3ckg.m0QoHt-5MdR0MH501npcL8aJof3Eu1h_9Zp0ceNm8e4g.PNG.guri4you%2F%25BB%25F6%25B1%25F2_%25BD%25C9%25B8%25AE%25C5%25D7%25BD%25BA%25C6%25AE1.png&type=sc960_832', }, { src: 'https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAxNjExMjFfMjM2%2FMDAxNDc5NjY5MjEyOTEz.13R8uiaA0T8rJnLPJICAib4oVtrAzA424jbDMC9a3ckg.m0QoHt-5MdR0MH501npcL8aJof3Eu1h_9Zp0ceNm8e4g.PNG.guri4you%2F%25BB%25F6%25B1%25F2_%25BD%25C9%25B8%25AE%25C5%25D7%25BD%25BA%25C6%25AE1.png&type=sc960_832', }, { src: 'https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAxNjExMjFfMjM2%2FMDAxNDc5NjY5MjEyOTEz.13R8uiaA0T8rJnLPJICAib4oVtrAzA424jbDMC9a3ckg.m0QoHt-5MdR0MH501npcL8aJof3Eu1h_9Zp0ceNm8e4g.PNG.guri4you%2F%25BB%25F6%25B1%25F2_%25BD%25C9%25B8%25AE%25C5%25D7%25BD%25BA%25C6%25AE1.png&type=sc960_832', }], Comments: [{ User: { nickname: 'jj4', }, content: 'redux를 학습 중입니다.', }, { User: { nickname: 'jj3', }, content: '다음은 sage를 학습 예정임.', }] }], imagePaths: [], postAdded: false, } const ADD_POST = 'ADD_POST'; export const addPost = { type: ADD_POST, } const dummyPost = { id: 2, content: '더미데이터입니다.', User: { id: 1, nickname: 'jj1', }, Images: [], Comments: [], }; const reducer = (state = initialState, action) => { switch (action.type) { case ADD_POST: return { ...state, mainPosts: [dummyPost, ...state.mainPosts], postAdded: true, }; default: return state; } }; export default reducer; 6. PostForm.js import React, { useCallback, useState, useRef } from 'react'; import { Form, Input, Button } from 'antd'; import { useSelector, useDispatch } from 'react-redux'; import { addPost } from '../reducers/post'; const PostForm = () => { const { imagePaths } = useSelector((state) => state.post); const dispatch = useDispatch(); const imageInput = useRef(); const [text, setText] = useState(''); const onChangeText = useCallback((e) => { setText(e.target.value); }, []); const onSubmit = useCallback(() => { dispatch(addPost); setText(''); }, []); const onClickImageUpload = useCallback(() => { imageInput.current.click(); }, [imageInput.current]); return ( <Form style={{ margin: '10px 0 20px' }} encType="multipart/form-data" onFinish={onSubmit}> <Input.TextArea value={text} onChange={onChangeText} maxLength={140} placeholder="어떤 신기한 일이 있었나요?" /> <div> <input type="file" multiple hidden ref={imageInput}/> <Button onClick={onClickImageUpload}>이미지 업로드</Button> <Button type="primary" style={{ float: 'right' }} htmlFor="submit">짹짹</Button> </div> <div> {imagePaths.map((v) => ( <div key={v} style={{ display: 'inline-block'}}> <img src={v} style={{ width: '200px' }} alt={v} /> <div> <Button>제거</Button> </div> </div> ))} </div> </Form> ) }; export default PostForm; 7. PostCard.js import React from 'react'; const PostCard = () => { return ( <div> PostCard </div> ); }; export default PostCard; 8. user.js import { HYDRATE } from 'next-redux-wrapper'; // initialState 부분 const initialState = { user: { isLoggedIn: false, user: null, signUpData: {}, loginData: {}, }, post: { mainPosts: [], } }; // [로그인] action creator export const loginAction = (data) => { return { type: 'LOG_IN', data, } }; // [로그아웃] action creator export const logoutAction = (data) => { return { type: 'LOG_OUT', } }; // reducer const rootReducer = (state = initialState, action) => { switch (action.type) { case HYDRATE: console.log('HYDRATE', action); return { ...state, ...action.payload }; case 'LOG_IN': return { ...state, user: { ...state.user, isLoggedIn: true, user: action.data, }, }; case 'LOG_OUT': return { ...state, user: { ...state.user, isLoggedIn: false, user: null, }, }; default: return state; } }; export default rootReducer; 다소 많은 양의 글 내용이지만, 시간이 허락되실 때 답변 주시면, 참 감사할 것 같습니다! 오늘 하루도 고생많으셨고, 이번 한 주도 파이팅입니다! 늘 양질의 강의 감사합니다 ^^
-
해결됨Redux vs MobX (둘 다 배우자!)
redux 글 수정
안녕하세요 수업 잘 듣고 있습니다! 해결이 되지 않아서 질문 남깁니다 ㅠㅠㅠㅠ 리덕스로 글 수정을 시도 중입니다 현재 글 list의 내용을 input에 불러온 뒤 수정한 내용과 같이 보내서 수정을 하고 있습니다 문제는 list를 콘솔에 찍게 되면 2가지의 목록이 불러와지고 있습니다 2번째의 list에는 현재 게시물의 목록, 첫번째는 그 전에 눌렀던 목록이 나오고 있습니다 제가 원하는 list는 두번째의 목록의 list인데 input창까지는 두번째의 list가 잘 불러와지지만 postEditInfo에서는 첫번째 목록이 불러와진 상태이고 이 데이터를 서버에 보내게 되면 그 전에 눌렀던 목록의 list가 현재 목록에 덮어지는 현상이 발생하고 있습니다 그래서 default를 ' ' 로 변경을 하고 나서 목록을 수정하게 되면 postEditInfo가 수정하지 않은 목록은 undefined로 뜨게되고 서버에서 undefiend인 목록은 수정을 하지 않게 막아놓은 상태라서 일단 제대로 수정이 되고 있습니다 하지만 한번 수정을 하고나서 다른 게시물을 수정하게 된다면 원래 남아있던 postEditInfo가 다른게시물에 덮어집니다 ㅠㅠㅠ 왜 두번 목록이 불러와지는지, 현재의 목록을 한번만 불러오려면 어떻게 해야 되는지 궁금합니다 ㅠㅠㅠ const list = useSelector((state)=> state.postsDetailReducer) console.log('list====',list) const [postEditInfo, setPostEditInfo] = useState({ restaurant_name: list.restaurant_name, recruitment_personnel: list.recruitment_personnel, delivery_fee: list.delivery_fee, address: list.address, body: list.body, }) ... <input defaultValue={list.address} onChange={handleInputValue('address')} /> const postDetailInitialState = { address: null, body: null, category_food: null, closed: null, created_at: null, delivery_fee: null, id: null, lat: null, lng: null, recruitment_personnel: null, restaurant_name: null, user_id: null, }; const postsDetailReducer = (state=postDetailInitialState, action) => { switch(action.type){ case SHOW_POST_LIST_SUCCESS: let post = action.payload.data.data; let newData = { address: post.address, body: post.body, category_food: post.category_food, closed: post.closed, created_at: post.created_at, delivery_fee: post.delivery_fee, id: post.id, lat: post.lat, lng: post.lng, recruitment_personnel: post.recruitment_personnel, restaurant_name: post.restaurant_name, user_id: post.user_id, } return Object.assign({}, state, newData); case SHOW_POST_EDIT_SUCCESS: return Object.assign({}, state, { contendId: post.contendId, restaurant_name: post.restaurant_name, recruitment_personnel: post.recruitment_personnel, delivery_fee: post.delivery_fee, address: post.address, body: post.body, }); default: return ''; // default: return state; // 원래 코드 } }
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
코드 질문이요
10:00분에서 useEffect(() => { if (!(me && me.id) { Router.push('/'); } }, [me &&.id]); if (!me) { return null; }; 이 코드를 if (!me) { Router.push('/'); return null; }; 이렇게 코드 바꿔도 오류는 없던데 밑에 껄로해도 별 차이 없는건가요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
안녕하세요 !! 존경하는 제로초님 질문이 있습니다!
안녕하세요 제로초님 ! 수업 열심히 듣고 있습니다. 에러에 관한 질문은 아니고 개인적인 질문입니다 ㅜ.ㅜ 원래 리액트를 조금은 공부한 대학생이고, 협업을 하기전 강의로 부족한 부분을 알아가기 위해 듣고 있습니다. next.js도 공부해보고 싶었구요! Q0. 저는 redux에서 액션을 생성할 때 redux-actions를 이용해서 createAction을 사용하고, switch 대신 handleActions를 사용하고 있습니다. 이번 수업에서도 사용해서 진행하고 있습니다. 제 생각에는 취향 혹은 손에 익은 차이가 가장 클 것 같아서 swtich 혹은 return 형식으로 리덕스 액션 생성 함수와 아래 리덕스 타입에 따른 실제 상태 변환을 해주신다고 생각하는데, 그게 맞을까요 ? Q1. 컨테이너를 따로 분리하지 않고 컴포넌트 안에서 바로 액션 디스패치를 넣어주시고 있는데, 강의 도중에 설명도 해주셨지만, 요즈음은 이렇게 바로 컴포넌트에 넣는 것으로 많이 쓰는지 궁금합니다. 저녁에 질문 드려 죄송합니다 !! 초보자라서 질문이 혹시 이상하다면 말씀해주시면 감사하겠습니다.
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
실제 배포한 ip에서는 쿠키가 생성이되지않고 passport중에deserializeUser호출이 안됩니다.
안녕하세요 조현영 선생님 제가지금 해당 강의를 통해서 개인 프로젝트를 진행중인데 문제가 발생이 됬습니다. 클라이언트와 백엔드 다 우분트 환경에서 잘 작동해서 실제 배포한 ip주소로 들어가면 정상적으로 화면이 보여집니다. 클라이언트 서버: 다 작동이 잘 되고 회원가입 기능도 잘 작동해서 실제 해당http://13.125.96.64 쪽으로 요청을 하여 데이터베이스도 잘 생성이되고 됩니다. 근데 문제가 local로 성공적으로 로그인을하면 passport.js 쪽에서 serializeUser 한번 실행을하고 쿠키가 생겨야하는데 생기질 않습니다. 그리고 다시 메인 화면으로 돌아오면 LOAD_MY_INFO_REQUEST action으로 통해서 cookie 와 같이 서버로 전송을해서 deserializeUser도 실행이 되야하는데. deserializeUser도 실행이 안됩니다. 제 로컬에서는 모든게 다 잘 작동합니다. 로컬에서 프론트: 로그인 하면 잘 작동합니다. 로컬에서 백엔드 pm2 환경 보시면 쿠키도 잘 생성되고 passport.js 에서 deserializeUser 도 잘 작동되는게 보입니다. 하지만 배포한 ip에서는 쿠키도 생성이 되질않고 deserializeUser 도 작동하지 않습니다위 사진은 제가 로그인이 성공하고 다시 메인 페이지로 돌아온 화면입니다 성공적으로 로그인이 되도 쿠키는 여전히 생성되지 않았습니다. 위 사진은 제가 로그인이 성공하고 다시 메인 페이지로 돌아온 화면입니다 성공적으로 로그인이 되도 쿠키는 여전히 생성되지 않았습니다. 백엔드쪽 봐도serializeUser 으로 로그인이 성공하고 deserializeUser는 호출이 되질 않습니다. back/app.js 소스코드입니다. const express = require('express'); const PORT = 80; const app = express(); const cors = require('cors'); const effectRouter = require('./routers/effect'); const userRouter = require('./routers/user'); const effectsRouter = require('./routers/effects'); const db = require('./models'); const session = require('express-session'); const cookieParser = require('cookie-parser'); const dotenv = require('dotenv'); const passport = require('passport'); const passportConfig = require('./passport'); const morgan = require('morgan'); const hpp = require('hpp'); const helmet = require('helmet'); db.sequelize .sync() .then(() => { console.log('db 연결 성공'); }) .catch(console.error); passportConfig(); dotenv.config(); app.use(cookieParser(process.env.EFFECTSHOP_SECRET)); app.use( session({ saveUninitialized: false, resave: false, secret:process.env.EFFECTSHOP_SECRET, }) ) if(process.env.NODE_ENV === 'production'){ app.use(morgan('combined')); app.use(hpp()); //보안에 도움되는 라이브러리 app.use(helmet()); }else{ app.use(morgan('dev')); } app.use(passport.initialize()); // 패스포트 설정 미들웨어에 추가. app.use(passport.session()); app.use(express.json()); app.use(express.urlencoded({extended: true})); app.use(cors({ origin:["http://localhost:3000","http://54.180.81.148"], credentials:true, })); app.get('/',(req,res)=>{ res.send('hello express'); }) app.use('/effects' ,effectsRouter); app.use('/effect',effectRouter); app.use('/user', userRouter); app.listen(PORT, ()=>{ console.log(`server on! at http://localhost:${PORT}`); }); 더 자세한 코드를 보시길 원하신다면 여기에 제 소스코드를 올려 놓았습니다 ㅠㅠ 엄청난 고민끝에 여쭤봅니다 ㅜ 감사합니다. https://github.com/sungmin-choi/effectShopByHTML-CSS
-
해결됨Redux vs MobX (둘 다 배우자!)
useDispatch 관련 질문드립니다
안녕하세요 :) const dispatch = useDispatch(); const getTodoDatum = useCallback(() => { dispatch(fechLocal());}, [dispatch]); 이런식으로 dispatch를 사용하는 함수를 useCallback으로 감싸고 의존성 배열에 dispatch를 넣었는데요 상태가 변경될 때마다 disptach가 새로 생성되어서 getTodoDatum도 새로 생성되더라구요. 또 이 함수를 전달받는 컴포넌트들도 리렌더링되구요. 그래서 useMemo를 사용하려 했지만, 콜백함수 안에 useDispatch를 넣으니 hook은 컴포넌트 최상단에 넣어야한다는 에러가 뜨더라구요. 음.. 잘 전달됐을지 모르지만 요약하자면 useDispatch()의 값을 메모이제이션 할 수 있는 방법이 궁금합니다! 참고 할 수 있는 키워드 혹은 사이트만 알려주셔도 감사하겠습니다:)
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 유튜브 사이트 만들기
import {Icon} 에러 나시는 분
직접 공식문서 찾아드리려 했지만 이분께서 정리를 잘 해주셨습니다. ant design업그레이드 되면서 바뀐 문제입니다. 참고: https://shinye0213.tistory.com/317
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
zerocho 님 eslint 설정관련해서 질문이 있습니다.
안녕하세요 zerocho 님 eslint 설정관련해서 질문이 있습니다. eslint에서 env쪽에 node: true를 주시면서 node에서 사용하니까 주셨다고 하셨는데 next.js는 Browser환경에서 실행되지 않나요? server 코드가 따로 있는게 아닌 것 같아서요 혹시 이유를 알 수 있을까요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
다름이 아니라 DB 설계 관련 질문이 있습니다.
안녕하세요 강의 잘보고 있습니다! DB 관련해서 제가 몇가지 궁금한게 있는데 1. 예를 들어 하나의 테이블에서 다 대 다일때 즉 user 와 user에 다대다 일때 중간테이블 follow를 만들어주지 않고 한 User 테이블에 컬럼을 늘리는건 별로 안좋은 방식인가요? 예를 들어서 follow 테이블을 만들지 않고 User 테이블안에 팔로우, 팔로잉 수 컬럼을 넣는 방식 2. 다 대 다 관계일시 중간테이블 관련 다 대 다 관계일시 데이터베이스 이론적으로는 중간테이블을 만드는걸로 저도 배우긴 했는데 근데 이게 프로그래밍 관점에서 테이블을 너무 많이 늘리고 join이 많아질시 성능이 안좋다고 배웠던 기억이 있어서요 그래서 이게 실무에서도 다대다일시 중간테이블로 쪼개고 join을 자주 발생시키는지 궁금해요 로그인 같은경우에도 팔로우,잉,쓴글갯수를 유지하기 위해 로그인을 할때마다 post 테이블 follow 테이블 과의 3개의 테이블을 조인시켜서 select 하는 경우인데 과연 이런식의 3중조인을 로그인할때마다 해줘야 하는건가에 대한 생각 꼭 조인을 이렇게 많이해야 저 데이터를 가지고 올 수있나에 대한 DB설계에 대한 생각이 공존합니다. 아니면 제가 너무 오버하는 것일지 문제가 되지 않는 것인지... 그래서 실제로도 실무에서도 이런식으로 중간테이블과 db설계관련 또한 그걸로 인한 많은 join 관련해서 궁금하네요 ++ 제가 이런 생각이 든 이유가 게시판을 만들때 게시물 상세 페이지에 파일갯수랑, 댓글 갯수를 게시물 리스트에 명시해주는 로직을 짜다가 join 몇번해서 select 해서 가져와보자 했는데.. 다른분께서 이유는 말안하셨지만 join 그렇게 하지말라고 하셨거든요 그래서 그래서 게시물 DB에 갯수에 대한 컬럼을 늘려서 게시물 상세페이지 작성시 댓글, 파일 insert 할때 게시물 db에 갯수counting 해서 insert 하고 조인 없이 list 뿌려지는 형태로 바꿨거든요 그게 생각이나서요(insert 시 다른 db에는 count+1 insert 한 동작에 각 테이블의 2번의 insert 작업) 3. db 생성시 post.js user.js -> 실 테이블 posts, users 뒤에 s가 붙는데 이건 왜 붙는건 가요? 제가 실무 경험이 없어서 꼭 알고 싶은 포인트입니다.. ** 질문이 많은데 읽어주셔서 감사합니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
redex 연결 후 초기 데이터를 가져오지 못합니다.
안녕하세요. 선생님, 강의 잘 듣고 있습니다. 리덕스가 AppLayout 에 연결은 된 것 같은데, 초기 값을 가져오지 못합니다. state 에 user 가 없다는 오류만 자꾸 나오는데, 어떤 것을 한번 봐야 할까요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
"logInDone" state값이 다른 이유가 궁금합니다.
안녕하세요. 먼저 이런 좋은 강의를 듣게 해주셔서 감사합니다. 질문) pages/index.js 와 components/UserProfile.js 에서 state값이 다른 이유가 궁금해서 질문드립니다. 아래 사진 순서) pages/index.js components/UserProfile.js 콘솔창
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
faker 이미지
faker 이미지가 이런식으로 나오는거면 컴터 사양문제일까요??
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
postcss plugin 에 관한 오류가 나타납니다 ㅜ
전 강좌에서 캐루셀 설정후에 npm run dev를 통하여 확인해보려 하는데 ready - started server on 0.0.0.0:3060, url: http://localhost:3060 Unknown error from PostCSS plugin. Your current PostCSS version is 8.4.5, but autoprefixer uses 6.0.23. Perhaps this is the source of the error below. error - ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[2].oneOf[7].use[1]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[2].oneOf[7].use[2]!./node_modules/antd/dist/antd.css BrowserslistError: Unknown browser query `dead` at Array.reduce (<anonymous>) 이러한 에러가 뜹니다 ㅜ 구글링해서 계속 찾아보고있는 중인데 도대체 무슨이유인지 모르겠습니다 ㅜㅜㅜ 부탁으려요
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
글 작성시 UserID가 DB에 저장안되는 이슈
안녕하세요~ 글 작성시 UserID가 DB에 저장안되는 이슈가 있어서 질문드립니다. 게시글을 작성 후에 TypeError: Cannot read properties of null (reading 'nickname') 에러가 납니다. 지금까지 해본 것 1. 다른 답글에 적어주신 내용처럼 router/post.js 쪽에서 req.user.id를 확인해보았습니다. 위에 사진처럼 작성자의 아이디가 나왔습니다. 2. MySQL의 DB에 보니까 UserId가 올라오고 있지 않습니다. 3. res.send로 받은 result를 console.log를 찍어보니까 UserId가 없었습니다. 4. MySQL 에 UserId를 직접 입력 (1) 해보니까 에러 없이 잘 나왔습니다. 제 생각에는 Model에서 에러가 발생한 것 같습니다. 깃허브에 올려주신 것을 보니까 5버전에 클래스로 하신 코드이신데 강의에서는 위와 같이 사용중이라서 참고를 해보았으나 DB 등록시 UserId가 입력이 안되는 것 같습니다.알려주신대로 기능 추가시 흐름을 정리해서 보면서 생각해보니까 여기까지는 에러가 왜 낫는지 알겠는데 몇시간을 고민해도 버그가 수정이 안되서 송구스러운 마음을 가지고 질문드립니다. 깃허브 주소 : https://github.com/hyunjoogo/react-nodebird
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
리덕스 설치강좌 듣고 있는데요, 제 vscode에서 설치가 제대로 안됩니다.(win10 64bit)
리덕스 설치강좌 듣고 있는데요, 제 vscode에서 설치가 제대로 안됩니다.(win10 64bit) npm i next-redux-wrapper@6 명령어를 넣었을때 -> npm i redux 명령어를 입력했을때 -> 제대로 설치가 안된거 같은데 어떻게 해야 하나요?
-
해결됨Slack 클론 코딩[실시간 채팅 with React]
강의소개에서
강의소개보면 swr(리덕스대체) 라고 나와있는데 swr도 리덕스처럼 상태관리를 하는건가요?