월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
[공유] Post 수정 취소 후 다시 수정시 이전 수정 값이 남아 있는 문제 해결
PostCardContent에서 취소 버튼을 클릭시 바로 onCancelUpdate()를 하게 되면 editText의 값이 리셋되지 않습니다.그래서 다시 수정 버튼을 클릭하면, TextArea에 postData가 보이는 것이 아닌, 이전에 수정을 하려다가 취소할 당시의 값이 남아있게 됩니다! (해당 내용은 제로초님 sleact 레파지토리에 pull request 하였습니다.) 취소 버튼 클릭시 editText를 리셋하고 onCancelUpdate를 실행할 함수를 만들어주면 됩니다!const onClickCancel = useCallback(() => { setEditText(postData); onCancelUpdate(); });<Button type="danger" onClick={onClickCancel}>취소</Button>
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
s3 연결하기 강의 중에
안녕하세요 제로초님 항상 질문에 빨리 답변 달아주셔서 감사합니다. 백엔드에 문제가 있는거 같은 pm2 monit은 아래와 같이 뜹니다 const express = require("express"); const session = require("express-session"); const cookieParser = require("cookie-parser"); const cors = require("cors"); const app = express(); const postRouter = require("./routes/post"); const userRouter = require("./routes/user"); const postsRouter = require("./routes/posts"); const hashtagRouter = require("./routes/hashtag"); const db = require("./models"); const passportConfig = require("./passport"); const passport = require("passport"); const dotenv = require("dotenv"); const morgan = require("morgan"); const path = require("path"); const hpp = require("hpp"); const helmet = require("helmet"); dotenv.config(); db.sequelize .sync() .then(() => { console.log("db 연결성공"); }) .catch(console.error); passportConfig(); //모드변경 if (process.env.NODE_ENV === "production") { app.use(morgan("combined")); app.use(hpp()); app.use(helmet({ contentSecurityPolicy: false })); app.use( cors({ origin: "http://sansbook.co.kr", credentials: true, }) ); } else { app.use(morgan("dev")); app.use( cors({ origin: true, credentials: true, }) ); } // app.use( // cors({ // origin: [ // "http://localhost:3000", // "http://sansbook.co.kr", // "http://43.200.92.114", // ], // credentials: true, // }) // ); app.use("/", express.static(path.join(__dirname, "uploads"))); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use( session({ saveUninitialized: false, resave: false, secret: process.env.COOKIE_SECRET, cookie: { httpOnly: true, secure: false, domain: process.env.NODE_ENV === "production" && ".sansbook.co.kr", }, }) ); app.use(passport.initialize()); app.use(passport.session()); app.get("/", (req, res) => { res.send("hello express"); }); app.use("/posts", postsRouter); app.use("/post", postRouter); app.use("/user", userRouter); app.use("/hashtag", hashtagRouter); app.listen(80, () => { console.log("서버실행중!"); });
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
회원가입시 500 에러
{ "name": "sansbook-back", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "dev": "nodemon app", "start": "cross-env NODE_ENV=production pm2 start app.js" }, "author": "jangsan", "license": "ISC", "dependencies": { "bcrypt": "^5.1.0", "cookie-parser": "^1.4.6", "cors": "^2.8.5", "cross-env": "^7.0.3", "dotenv": "^16.0.3", "express": "^4.18.2", "express-session": "^1.17.3", "helmet": "^6.1.5", "hpp": "^0.2.3", "morgan": "^1.10.0", "multer": "^1.4.5-lts.1", "mysql2": "^3.2.0", "passport": "^0.6.0", "passport-local": "^1.0.0", "pm2": "^5.3.0", "sequelize": "^6.30.0", "sequelize-cli": "^6.6.0", "session": "^0.1.0" }, "devDependencies": { "nodemon": "^2.0.22" } } const express = require("express"); const session = require("express-session"); const cookieParser = require("cookie-parser"); const cors = require("cors"); const app = express(); const postRouter = require("./routes/post"); const userRouter = require("./routes/user"); const postsRouter = require("./routes/posts"); const hashtagRouter = require("./routes/hashtag"); const db = require("./models"); const passportConfig = require("./passport"); const passport = require("passport"); const dotenv = require("dotenv"); const morgan = require("morgan"); const path = require("path"); const hpp = require("hpp"); const helmet = require("helmet"); dotenv.config(); db.sequelize .sync() .then(() => { console.log("db 연결성공"); }) .catch(console.error); passportConfig(); //모드변경 if (process.env.NODE_ENV === "production") { app.use(morgan("combined")); app.use(hpp()); app.use(helmet()); } else { app.use(morgan("dev")); } app.use( cors({ origin: ["http://localhost:3000", "sansbook.com", "http://15.164.99.87"], credentials: true, }) ); app.use("/", express.static(path.join(__dirname, "uploads"))); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use( session({ saveUninitialized: false, resave: false, secret: process.env.COOKIE_SECRET, }) ); app.use(passport.initialize()); app.use(passport.session()); app.get("/", (req, res) => { res.send("hello express"); }); app.use("/posts", postsRouter); app.use("/post", postRouter); app.use("/user", userRouter); app.use("/hashtag", hashtagRouter); app.listen(80, () => { console.log("서버실행중!"); }); 회원가입 할떄 마다 500에러가 나는데 프론트 문제인가요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
Aborting
git 저장소를 불러오는중에 Aborting떠서git reset --hard를 해도 계속 최신 커밋이 안뜹니다 ㅠㅠHEAD is now at 95de5ce Update: back start script계속 이게 뜨면서 pull해도 Aborting이 계속 나오네요 ㅠㅠ
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
mysql_secure_installation 정책에 관해
제가 다른게시물 보고 https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-20-04이거까지 했는데 계속 새로운 비밀번호 입력 하라고 뜨네요 ㅠㅠ이런 경우 어떻게 해야할까요 비밀번호도 보안수준에 맞게 했는데 계속 뜨네요 ㅠㅠ
- 해결됨[리뉴얼] React로 NodeBird SNS 만들기
redux-saga 코드 정리는 어떻게 하는게 좋나요?
강좌를 듣고나면 saga의 user.js 랑 post.js 쪽 파일이 코드줄이 굉장히 길어지는데요막상 파일을 쪼개서 정리를 하려고해도 연관되는 상태들이 많아서 결국엔 한쪽으로 몰게되네요어쩔 수 없는 부분인가요? 사실 강좌를 듣고 프로젝트를 하나 완성했는데 saga 부분을 쪼갤 수 있으면 최종적으로 수정하고 마무리 할거고 아니면 바로 타입스크립트 강좌 듣고 repo 하나 더 파서 지금 프로젝트 타입스크립트로 정리해보려 합니다 ㅎ좋은 강좌 만들어주셔서 정말 감사하고 다음 강좌는 전용 링크로 수수료없이 결제하겠습니다 ~감사합니다 !
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
react query를 이용한 로그인 유저 정보 가져오는 방법
깃허브에 올려주신 react query의 부분을 보고 공부하는 과정중에 궁금한 점이 생겨 질문드립니다.로그인 정보를 가져오기 위한const { data: me } = useQuery<User>('user', loadMyInfoAPI);useQuery를 이용해 캐싱한 데이터를 가져오는 방법과,리덕스, 리코일의 전역관리 상태 라이브러리를 이용하여 로그인 정보를 관리하는 방법중에 어떠한 방법이 나은 방향인지 궁금합니다.저의 경우는 전역 상태로 관리해, 데이터를 한 번만 가져와서 여러 곳에서 사용할 수 있어서 코드의 중복을 줄일 수있다고 생각하였는데 왜 useQuery를 이용해 캐싱한 데이터를 가져오는 방법을 사용하였는지 궁금합니다.
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
REQUEST를 실행해도 loadPostLoading이 바로 바뀌지 않습니다.
안녕하세요 제로초님! const { mainPosts, hasMorePosts, loadPostsLoading } = useSelector( (state) => state.post, ); useEffect(() => { function onScroll() { if ( window.scrollY + document.documentElement.clientHeight > document.documentElement.scrollHeight - 300 ) { if (hasMorePosts && !loadPostsLoading) { console.log('로딩상태 ; ', loadPostsLoading); console.log('불러오기'); dispatch({ type: LOAD_POSTS_REQUEST, }); } } } window.addEventListener('scroll', onScroll); return () => { window.removeEventListener('scroll', onScroll); }; }, [hasMorePosts, loadPostsLoading]);현재 여기까지 코딩이 진행된 상태인요! 콘솔로 찍어보니이렇게 두번 REQUEST를 보내게 됩니다.리덕스를 찍어봤을 때는이렇게 나옵니다.reducers 부분은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; ...saga > post.js 코드는function loadPostsAPI(data) { return axios.get('/api/post', data); } function* loadPosts(action) { try { // const result = yield call(loadPostsAPI, action.data) yield delay(1000); const id = shortid.generate(); 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); }이 상태입니다.조건문에서 !loadPostsLoading < 이걸 지우면 엄청난 양으로 REQUEST가 보내지는 것을 보니 !loadPostsLoading 이게 먹히는 것 같기는 합니다.왠지 REQUEST가 보내진 후 loadPostsLoading이 true로 변경된 것 같기는 한데 이게 useEffect 코드에서는 아직 false로 인식해서 또 REQUEST를 보내는 것이 아닌가 하는게 제 추측인데요, 맞을까요?ㅠㅠ
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
about.js에서 getStaticProps
export const getStaticProps = wrapper.getStaticProps(async (context) => { console.log("getStaticProps"); context.store.dispatch({ type: LOAD_USER_REQUEST, data: 1, }); context.store.dispatch(END); await context.store.sagaTask.toPromise(); });about.js에서 위에 코드를 입력하면 사이트에 연결할수 없음이라고 뜨는데 이코드도 버전 차이면 어떻게 바꿔야 하는지 알려주시면 감사하겠습니다
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
해시태그 검색하기 강의에서
import { Card, Button, Avatar, Popover, List, Comment } from "antd"; import { RetweetOutlined, HeartOutlined, MessageOutlined, HeartTwoTone, EllipsisOutlined, } from "@ant-design/icons"; import { useDispatch, useSelector } from "react-redux"; import PropTypes from "prop-types"; import PostImages from "./PostImages"; import { useCallback, useEffect, useState } from "react"; import CommentForm from "./CommentForm"; import PostCardContent from "./PostCardContent"; import FollowButton from "./FollowButton"; import { REMOVE_POST_REQUEST, LIKE_POST_REQUEST, UNLIKE_POST_REQUEST, RETWEET_REQUEST, } from "../reducers/post"; import Link from "next/link"; const PostCard = ({ post }) => { const dispatch = useDispatch(); const { removePostLoading } = useSelector((state) => state.post); const [commentFormOpened, setCommentFormOpened] = useState(false); const id = useSelector((state) => state.user.me?.id); const onLike = useCallback(() => { if (!id) { return alert("로그인이 필요합니다."); } return dispatch({ type: LIKE_POST_REQUEST, data: post.id, }); }, [id]); const onUnLike = useCallback(() => { if (!id) { return alert("로그인이 필요합니다."); } return dispatch({ type: UNLIKE_POST_REQUEST, data: post.id, }); }, [id]); const onToggleComment = useCallback(() => { setCommentFormOpened((prev) => !prev); }, []); const onRemovePost = useCallback(() => { if (!id) { return alert("로그인이 필요합니다."); } return dispatch({ type: REMOVE_POST_REQUEST, data: post.id, }); }, [id]); const onRetweet = useCallback(() => { if (!id) { return alert("로그인이 필요합니다."); } return dispatch({ type: RETWEET_REQUEST, data: post.id, }); }, []); const liked = post.Likers?.find((v) => v.id === id); return ( <div style={{ marginBottom: 10 }}> <Card cover={post.Images[0] && <PostImages images={post.Images} />} actions={[ <RetweetOutlined key="retweet" onClick={onRetweet} />, liked ? ( <HeartTwoTone twoToneColor="#eb2f96" key="heart" onClick={onUnLike} /> ) : ( <HeartOutlined key="heart" onClick={onLike} /> ), <MessageOutlined key="message" onClick={onToggleComment} />, <Popover key="more" content={ <Button.Group> {id && post.user?.id === id ? ( <> <Button>수정</Button> <Button type="danger" onClick={onRemovePost} loading={removePostLoading} > 삭제 </Button> </> ) : ( <Button>신고</Button> )} </Button.Group> } > <EllipsisOutlined /> </Popover>, ]} title={ post.RetweetId ? `${post.user.nickname}님이 공유하셨습니다` : null } extra={id && <FollowButton post={post} />} > {post.RetweetId && post.Retweet ? ( <Card cover={ post.Retweet.Images[0] && ( <PostImages images={post.Retweet.Images} /> ) } > <Card.Meta avatar={ <Link href={`/user/${post.Retweet.user.id}`}> <a> <Avatar>{post.Retweet.user.nickname[0]}</Avatar> </a> </Link> } title={post.Retweet.user.nickname} description={<PostCardContent postData={post.Retweet.content} />} /> </Card> ) : ( <Card.Meta avatar={ <Link href={`/user/${post.user.id}`}> <a> <Avatar>{post.user.nickname[0]}</Avatar> </a> </Link> } title={post.user.nickname} description={<PostCardContent postData={post.content} />} /> )} </Card> {commentFormOpened && ( <div> <CommentForm post={post} /> <List header={`${post.Comments.length}개의 댓글`} itemLayout="horizontal" dataSource={post.Comments} renderItem={(item) => ( <li> <Comment author={item.user?.nickname} avatar={ <Link href={`/user/${post.user?.id}`}> <a> <Avatar>{post.user?.nickname[0]}</Avatar> </a> </Link> } content={item.content} /> </li> )} /> </div> )} </div> ); }; PostCard.propTypes = { post: PropTypes.shape({ id: PropTypes.number, user: PropTypes.object, content: PropTypes.string, createdAt: PropTypes.string, Comment: PropTypes.arrayOf(PropTypes.object), Images: PropTypes.arrayOf(PropTypes.object), Likers: PropTypes.arrayOf(PropTypes.object), RetweetId: PropTypes.number, Retweet: PropTypes.objectOf(PropTypes.any), }).isRequired, }; export default PostCard; 아바타를 클릭하면 해당 아이디 정보하고 그 아이디 게시물만 떠야하는데 해당 아이디 프로필은 잘뜨는데 게시물이 다른사람 게시글까지 같이 뜹니다. 참고로 저는 post.User를 u로 바꿔야지만 뜹니다
- 해결됨[리뉴얼] React로 NodeBird SNS 만들기
비동기 요청시 새로고침
실제 몇몇 서비스를 보면 글 작성이나 수정같은 비동기 요청이 성공한 후에 새로고침을 하는데이 강좌와 같이 Next.js를 사용하는 리액트 개발은 새로고침을 하는게 맞는건가요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
사용 게시글 강의에서 SerializableError
SerializableError: Error serializing `.initialState.post.loadPostsError` returned from `getServerSideProps` in "/user/[id]". Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value all together. at isSerializable (/Users/js/Desktop/sansbook/node_modules/next/dist/lib/is-serializable-props.js:7:95) at /Users/js/Desktop/sansbook/node_modules/next/dist/lib/is-serializable-props.js:7:503 at Array.every (<anonymous>) at isSerializable (/Users/js/Desktop/sansbook/node_modules/next/dist/lib/is-serializable-props.js:7:304) at /Users/js/Desktop/sansbook/node_modules/next/dist/lib/is-serializable-props.js:7:503 at Array.every (<anonymous>) at isSerializable (/Users/js/Desktop/sansbook/node_modules/next/dist/lib/is-serializable-props.js:7:304) at /Users/js/Desktop/sansbook/node_modules/next/dist/lib/is-serializable-props.js:7:503 at Array.every (<anonymous>) at isSerializable (/Users/js/Desktop/sansbook/node_modules/next/dist/lib/is-serializable-props.js:7:304)이 에러가 떴는데 user-[id].js에서 getServerSideProps 코드가 잘못되었다는 뜻인가요? 아니면 undefined나 null을 어떻게 처리할것인지..잘모르겠습니다
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
서버에 코드를 올렸는데 mixed content에러 발생중입니다.
안녕하세요. 제로초님.우선 학습관련 내용이 아닌 내용에 대해 질문드리게 되어 죄송합니다.혹여 문제가 될 시 질문 글을 삭제하도록 하겠습니다.몇 일 동안 해결하려 했으나 해결이 잘 되지 않아 이 곳을 통해 질문드리게 되었습니다.fe작업물을 테스트 서버에 반영하였으나,로그인을 시도할 때 아래와 같은 에러가 발생중입니다.xhr.js:247 Mixed Content: The page at 'https://도메인주소/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://백엔드api주소'. This request has been blocked; the content must be served over HTTPS. 구글링을 해본 결과 메타 태그를 index.html에 삽입하라고 하여 삽입을 해보았으나,pending로 통신 자체가 불가능한 상황입니다.http-proxy-middleware 라이브러리를 사용하여 setproxy.js파일도 세팅을 해보았으나 여전히 위와 같은 문제가 발생중입니다..env 파일을 생성하여 백엔드 api를 프록시로 설정을 하였고, 프론트엔드 host도 지정을 하였는데 위와 같은 문제가 발생 중입니다. 도무지 해결이 되지 않아 여기 질문드린 점 다시 한번 사과드리겠습니다.혹여 문제가 되면 질문 글은 바로 삭제하도록 하겠습니다.
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
서버사이드렌더링 준비하기 강의 질문
강의에 올라와 있는 pages폴더에서 index.js 파일 getServerSideProps부분이 저도 store.dispatch오류가 나서 고차함수로 바꾸어 주니까 해결됬습니다. 근데 이유를 잘모르겠습니다 ㅠㅠexport const getServerSideProps = wrapper.getServerSideProps( (store) => async () => { store.dispatch({ type: LOAD_MY_INFO_REQUEST, }); store.dispatch({ type: LOAD_POSTS_REQUEST, }); store.dispatch(END); await store.sagaTask.toPromise(); } );
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
thumb 폴더 생성이 안됩니다.
이미지 업로드 후 thumb 폴더가 생성 안됩니다!검색해보니 AWS Lambda 함수에서 S3 서비스를 호출할 때, 해당 Lambda 함수의 실행 역할이 S3 버킷에 대한 필요한 권한을 가지고 있지 않아서 발생한 것이라고 합니다...역할도 S3객체 읽기 전용 권한 선택했습니다.근데 여기서 PutObject가 없는게 걸립니다..
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
쿠키공유 질문드립니다.
도메인까지 연결 성공했고 쿠키 공유만 해결하면 되는데 뭐 때문인지 감이 안잡힙니다....
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
413 Request Entity Too Large 질문
안녕하세요 선생님. 프로젝트 배포하고 나서 테스트 중에 특정 이미지를 업로드 하면 '413 Request Entity Too Large'라고 뜨는 오류를 발견했습니다. 특정 이미지 크기는 4.13mb정도구요. 일단 에러가 떠도 그대로 post요청을 보내면 업로드된 이미지가 보이긴 하는데 왜 이런 에러가 뜨는지 모르겠습니다..테스트 해보니까 세로 길이가 비교적 긴 이미지를 업로드 요청할 때 에러가 나는걸 확인했습니다.위 이미지가 프론트에서 나는 에러 상태 입니다. 오류 해결을 위해 먼저 back의 const upload = multer({ storage: multerS3({ s3: new AWS.S3(), bucket: 'fashionary-s3', key(req, file, cb) { cb(null, `original/${Date.now()}_${path.basename(file.originalname)}`) } }), limits: { fileSize: 20 * 1024 * 1024 }, // 20MB });여기서 limits부분이 20m인걸 확인하고, sudo vim /etc/nginx/nginx.conf 해서 http { ## # Basic Settings ## client_max_body_size 20M; sendfile on; tcp_nopush on; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; 위와 같이 http부분 설정을 20m으로도, 0으로도 설정 후 sudo service nginx reload 했는데도 특정 이미지 전송을 시도하면 같은 에러가 떠요..이럴 땐 어디를 봐야 하나요?
- 해결됨[리뉴얼] React로 NodeBird SNS 만들기
팔로우,언팔로우 강의
음 어디를 봐야할지 잘몰라서 글을 남깁니다 ㅠㅠ팔로우를 누르고 프로필을 넘어가면서다른 사람을 팔로우 했다가 자신을 팔로우 한것으로 바뀌네요 ㅠㅠ 그래서 팔로우하고 프로필 페이지로 넘어가면 팔로잉 목록하고 팔로워 목록에 자신 닉넴임이 둘다 뜹니다 ㅠㅠ일단 팔로우는 다른 사람 팔로우 했다고 정상적으로 뜹니다
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
안녕하세요 질문 있습니다.
안녕하세요 강의 관련된 내용은 아닌데 혹시 질문 드려도 괜찮을까요?이번에 슬랙에서 만두피님이 하신걸 보고 저에게 맞게 따라하고 있는데 잘 되지 않아 질문 드립니다.위와 같은 문제가 있는데 그 전에 비슷하게 사용했을땐 잘 되던 일이라 이것저것 해보다가 typescript 버전을 v4로 내리면 data가 IForm[] 으로 추론 된다는걸 알았습니다. typescript v5을 사용하려면 어떤 식으로 풀어가야 할까요?? rk는 v4 사용하고 있습니다.공홈에서는 저 fetchFormAPI에서 리턴 값 타입으로 Promise<IForm[]>으로 주면 된다는데 처음 보는 방법이라 맞는건지 아니면 그냥 연습을 위한 방법인지 잘 몰라 질문 드립니다.const { data, isLoading } = useQuery<IForm[]>(['forms'], () => fetchFormsAPI('test'));export function fetchFormsAPI(domain: string) { // 1 return api.get(`/forms?formId=${domain}`).then((response) => response.data); // 2 // return axios({ // method: 'get', // url: `/forms?formId=${domain}`, // }).then((response) => response.data); }export const api = axios.create({ baseURL: backUrl, withCredentials: true, }); 위 2번째 코드에서 2번을 사용하면 첫번째 사진 빨간 밑줄은 사라지는데 결국 타입 추론이 안되는건 같았습니다. 그리고 공식 문서 처럼 fetchFormAPI함수에 리턴 타입을 붙이고 useQuery에 타입을 빼면 아래와 같이 useQuery에서는 타입을 정상적으로 추론하지만 막상 데이터를 사용할 때는 이상한 값이 들어오는 것을 확인했습니다.export function fetchFormsAPI(domain: string): Promise<IForm[]> { // 1 return api.get(`/forms?formId=${domain}`).then((response) => response.data); }const { data, error, isLoading } = useQuery(['forms'], () => fetchFormsAPI('test'));typescript 버전을 v4로 내리면 정상 작동하는 것은 확인했습니다. 어제부터 해결을 못하고 있어 질문드립니다. 감사합니다.
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
스크롤링 success 문제
안녕하세요 제로초님인피니트 스크롤링 적용하는 부분에서 스크롤이 끝에 올 때마다 mainPosts가 10개씩 추가 되지 않고 한번에 50개(draft.hasMorePost = draft.mainPosts.length < 50;)가 추가 되는데 원래라면 스크롤을 끝까지 내릴 때마다 10개씩만 추가 되어야 하는 건가요?댓글에서 SUCCESS는 한 번만 와야 된다고 하셨는데 저는 처음 한 번만 게시글이 10개 추가(success 한 번)되고 이후에는 게시글이 50개가 될 때까지 한꺼번에 success가 들어옵니다콘솔에 inView를 찍어보니 처음 10개만 들어왔을 때는 true -> false로 값의 변화가 있는데 한번에 success 되는 부분에서의 inView의 값은 계속 true로 찍힙니다..이런 경우에는 어떻게 해결해야 되나요..??index.jsconst Home = () => { const dispatch = useDispatch(); const { me } = useSelector((state) => state.user); const { mainPosts, hasMorePost, loadPostsLoading } = useSelector((state) => state.post); const [ref, inView] = useInView(); useEffect( () => { dispatch({ type: LOAD_POSTS_REQUEST, }); }, []); useEffect( () => { if (inView && hasMorePost && !loadPostsLoading) { const lastId = mainPosts[mainPosts.length - 1]?.id; dispatch({ type: LOAD_POSTS_REQUEST, lastId, }); } }, [inView, hasMorePost, loadPostsLoading, mainPosts], ); return ( <AppLayout> {me && <PostForm />} {mainPosts.map((post) => <PostCard key={post.id} post={post} />)} <div ref={hasMorePost && !loadPostsLoading ? ref : undefined} style={{ height: 10, backgroundColor: 'red' }} /> </AppLayout> );