수강이 제한됩니다.
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결React로 NodeBird SNS 만들기
onsubmit, signup 페이지
onsubmit이 작동 안하길래 찾아보니 onFinish로 바뀐거 같습니다.
- 해결됨React로 NodeBird SNS 만들기
next js dispatch 관련 질문
_app.js getInitialProps 에서 LOAD_USER _REQUEST context.store.disptach 할 때 이 dispatch 도 비동기 함수 아닌가요? 만약 맞다면 await context.store.dispatch 를 사용해서 LOAD_USER_REQUEST 이 부분을 기다려도 동작은 하나요?
- 미해결React로 NodeBird SNS 만들기
aws 배포후 쿠키저장이 안됩니다
강의에서는 프론트주소에서 로그인을 하고 서버 주소로 가면 쿠키가 생성이 되는 모습이 보이는데 저는 서버에서 쿠키가 생성이 되지 않습니다. 로컬에서는 잘 작동하는데 AWS배포한 사이트에선 안되네요 혹시 어떠한 문제가 있는걸까요?
- 미해결React로 NodeBird SNS 만들기
React로 웹을 만들면 어플로 바꿀 때 React-Native를 사용하면 편한가요?
React로 웹사이트를 만들고 이를 어플로 서비스하고 싶으면 React Native로 다시 UI를 개발해야되는 거죠? 좀 더 쉽게 어플로 바꿀 수 있는 방법이 있나요?
- React로 NodeBird SNS 만들기
진지합니다!!!!!!!!!!
삭제된 글입니다
- 미해결React로 NodeBird SNS 만들기
window 를 바라보는 모듈의 경우 서버사이드렌더링 이슈
안녕하세요 선생님. nextjs 환경에서 react-draftjs 라는 외부 모듈을 사용해 편집기를 구현해보았고, ssr 관련 에러가 나왔으며 해결을 했는데 제가 맞게 이해하고 해결을 했는지 모르겠어서 질문드리게 됐습니다 ㅜㅜ 이슈 => 해당 편집기 페이지를 새로고침시 'window is not defined" 라는 에러를 발견해 해결 => nextjs에서 제공하는 dynamic 함수를 이용해 해당 모듈의 ssr 옵션을 false 처리하여 에러를 해결하였습니다. 제가 궁금한 건, 해당 편집기 페이지를 새로고침시 'window is not defined" 이 에러가 왜 떴는지입니다. 예상 ) 새로고침시 서버에서부터 이 모듈을 불러오고, react-draftjs 모듈이 window 객체를 바라보는 녀석이기 때문에 에러가 난 게 맞나요?
- 미해결React로 NodeBird SNS 만들기
AWS 배포후 쿠키관련..
현재 AWS로 페이지를 배포하고 한참된 후인데요.. 계속 잘돌아가고 있었는데 갑자기 로그인한후에 새로고침을 하면 로그인이 풀려버리네요. 쿠키 문제인거같아서 로컬에서 한번 실행해봤는데 이부분이 문제가 안되고 정상적으로 작동합니다.. 로컬에서 문제가 안되니 막막한데 어떤부분에서 문제가있는걸까요?
- 해결됨React로 NodeBird SNS 만들기
시간대가 이상하게 설정이 됩니다.
어느 환경에서 돌려도 시간대가 세계 표준시로 createdAt 칼럼에 생성이 됩니다. 로컬에서 돌려도 그렇구요 ec2인스턴스에 올려도 똑같구요 rds설정도 해보았는데 그렇게 나옵니다. 어떤 문제때문에 이런걸까요? moment라는 모듈을 깔아서 nodejs 시간대를 변경해보았는데도 이런 문제가 계속 고쳐지지 않고 발생하네요 시간대 설정할 수 있는 방법이 있을까요?
- 미해결React로 NodeBird SNS 만들기
안녕하세요
제가 위 강좌를 토대로 제 개인프로젝트를 만들었는데 다른점은 백엔드를 express로 안쓴다는점입니다. spring boot를 사용했는데 궁금한점이 있습니다. _app.js에 getInitialProps에서 isServer인경우 axios.defaults.headers.Cookie = cookie; 이런식으로 저장했는데 제 크롬에서 cookie가 날리고 완전새로고침을 해서 접속해도 axios.default.headers.Cookie값에는 cookie값이 남아있고 (ctx.req.headers.cookie에는 cookie값이 undefined입니다. 오직 axios값에만 저장되어있네요) 다른 기기로 처음접속해도 위 값이 찍히는데 위 같은경우는 왜 발생하는것인가요? 어떻게 해결해야할까요?
- 미해결React로 NodeBird SNS 만들기
제로초님
제로초님 알고리즘 적으로 궁금한게 있어서 질문 남깁니다. 예를 들어 이러한 객체가 있습니다. var aa = [ { seq: 1, user_id: "admin", artist:"Bl", log_id: "안녕", }, { seq: 1, user_id: "admin", artist:"Bl", log_id: "바이", } ] 이러한 객체를 { seq : 1, user_id: "admin", artist:"Bl", log: [ {log_id: 안녕}, {log_id: 바이} ] } 이렇게 중복 되는 부분을 없애 주고 아닌 것들은 log: [ {log_id: 안녕}, {log_id: 바이} ]이런식으로 묶어 주려고 하는데 어떤식으로 처리 하면 될런지 아무리 제로초님 강의를 보고 해도 아이디어가 떠오르질 않아서 질문 남기게 되었습니다.
- 미해결React로 NodeBird SNS 만들기
게시글 수정
이미지 파일 이름 정보를 가져와서 리듀써에서 src의 값만 배열로 다시 처리하려고 하는데, 리듀써에서 처리 하는 방식이 안되서 문의 드립니다. 문법이 잘 못됬나요?그리고 리듀써에 로그찍으면 안나오는 건가요?
- 미해결React로 NodeBird SNS 만들기
댓글의 댓글을 달려면 어떻게 해야되나요?
강의에서 MainPosts는 MainMessage로 Comments는 MainContents로 치환을 해서 대화목록 만들고 그 안에서 글을 작성하는 건 되는데 그 글에서 댓글을 다는 게 안되서 질문 드립니다 그 글에서 댓글은 Comments로 정의했고 reducers/message.js Comment 부분 export const initialState = { mainMessages: [{ id: 1, User: { id: 1, name: '이수현', }, Others: [{ id: 2, name: '김민지', }, { id: 3, name: '이우리', }], mainContents: [{ id: 1, User: { id: 2, name: '이수현', avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', }, content: '안녕', img: 'https://images.unsplash.com/photo-1484480974693-6ca0a78fb36b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1952&q=80', Comments: [], }, { id: 2, User: { id: 1, name: '김민지', avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', }, content: '안농', img: 'https://images.unsplash.com/photo-1484480974693-6ca0a78fb36b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1952&q=80', Comments: [], }], }], imagePaths: [], addMessageErrorReason: '', isAddingMessage: false, MessageAdded: false, isAddingContent: false, addContentErrorReason: '', contentAdded: false, isAddingComment: false, addCommentErrorReason: '', commentAdded: false, } const dummyContent = { id: 3, User: { id: 6, name: '김하나', avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', }, content: '더미 댓글입니다.', img: 'https://images.unsplash.com/photo-1484480974693-6ca0a78fb36b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1952&q=80', Comments: [], createdAt: new Date(), } case ADD_COMMENT_REQUEST:{ return{ ...state, isAddingComment: true, addCommentErrorReason:'', commentAdded: false, }; } case ADD_COMMENT_SUCCESS:{ const messageIndex = state.mainMessages.findIndex(v => v.id === action.data.messageId); const message = state.mainMessages[messageIndex]; const contentIndex = message.mainContents.findIndex(v => v.id === action.data.contentId); const content = state.mainBoards[contentIndex]; const Comments = [...content.Comments, dummyComment]; const mainContents = [...state.mainContents]; mainContents[contentIndex] = {...content, Comments}; return{ ...state, isAddingComment: false, mainMessages, mainContents, commentAdded: true, }; } case ADD_COMMENT_FAILURE:{ return{ ...state, isAddingComment:false, addCommentErrorReason: action.error, }; } sagas/message.js function addCommentAPI(){ } function* addComment(action) { try{ yield delay(2000); yield put({ type: ADD_COMMENT_SUCCESS, data: { messageId: action.data.messageId, contentId: action.data.contentId, }, }); }catch (e) { yield put({ type: ADD_COMMENT_FAILURE, error: e, }); } } function* watchAddComment() { yield takeLatest(ADD_COMMENT_REQUEST, addComment); } pages/messageCard.js return ( <div> {message.mainContents.map((v) => { return ( <> <Comment actions={[ <span key="comment-basic-like"> <Tooltip title="Like"> {React.createElement(action === 'liked' ? LikeFilled : LikeOutlined, { onClick: like, })} </Tooltip> <span className="comment-action">{likes}</span> </span>, <span key=' key="comment-basic-dislike"'> <Tooltip title="Dislike"> {React.createElement(action === 'liked' ? DislikeFilled : DislikeOutlined, { onClick: dislike, })} </Tooltip> <span className="comment-action">{dislikes}</span> </span>, // <span key="comment-basic-reply-to"><Icon type ="message" key="message" onClick={onToggleComment}/></span>, <span key="comment-basic-reply-to"> <Tooltip title="Reply"> {React.createElement(action === 'reply' ? MessageFilled : MessageOutlined, { onClick: () => { setContentIdState(v.id); console.log(v.id); }, })} </Tooltip> {/* <span className="comment-action">{dislikes}</span> */} </span>, ]} author={<a>{v.User.name}</a>} avatar={ <Avatar src={v.User.avatar} // alt="Han Solo" /> } content={ <p> {v.content} </p> } datetime={ <Tooltip title={moment().format('YYYY-MM-DD HH:mm:ss')}> <span>{moment().fromNow()}</span> </Tooltip> } > {/* {v.id == contentId?<MessageCardComment content={v} key={v}/>: <></>} */} {v.id == contentId ? <> <Form onSubmit={(e) => { e.preventDefault(); if (!user) { return alert('로그인이 필요합니다.'); } dispatch({ type: ADD_COMMENT_REQUEST, data: { messageId: message.id, contentId: v.id, }, }) }}> <Form.Item> <Input.TextArea rows={4} value={commentText} onChange={onChangeCommentText} /> </Form.Item> <Button type="primary" htmlType="submit" loading={isAddingComment}>입력</Button> </Form> <List header={`${v.Comments ? v.Comments.length : 0} 댓글`} itemLayout="horizontal" dataSource={v.Comments || []} renderItem={item => ( <li> <Comment author={item.User.name} avatar={<Avatar>{item.User.name[0]}</Avatar>} content={item.content} // datetime={item.createdAt} /> </li> )} /> </> : <></>} </Comment> <Divider /> </> ) })} </div> ); 저렇게 MessageId하고 ContentId를 두개를 넘기나요? 넘겼는데 자꾸 FAILURE라고 떠서 그리고 저기서 원래 onSubmitCommentForm을 함수로 빼려고 했는데 그럼 v.id 범위를 벗어나서 안에다가 넣었는데 함수로 하고 싶으면 onSubmitCommentForm(v.id)를 넣어줘도 되는 건가요? 만약 저기서 댓글의 댓글을 추가한다고 하면 messageId, contentId, commentId가 다 필요한 건가요? 그럼 그 변수는 props 여러개로 넘기는 건가요? 아니면 저렇게 한페이지에 있어야되는 건가요..?
- 미해결React로 NodeBird SNS 만들기
페이지형 게시판 만들고있습니다.
강의에서 배운걸 토대로 플젝중입니다. 게시판을 불러오는거는 성공했으나 ( 7개 불러오고싶으면 7개만 불러옴) 페이지형 게시판은 어떻게 구현해야하는지 감이 안잡힙니다.. ( 약 3일동안 작업했으나 결과물은 0이네요...) 여러 삽질중 알게된건데, 넥스트가 현재 동적데이터를 처리할 수 있게끔 Router()를 제공해준다고하네요 그렇지만 강의를 토대로 프로젝트를 하는거니 강의방식에 맞추고있습니다. 현재 프론트에서 express를 입혀주었고, 프론트 서버 라우터 경로는 server.get("/posts/:id", (req, res) => { return app.render(req, res, "/board", { id: req.params.id }); }); 이렇게, 사가에서 axios를 이용해서 /posts/:id로 경로를 보내주면 pages/board로 랜더되게끔 경로를 해주었고 front =>pages/board.js 는 아래 하단의 깃허브 코드와 같이 해줬습니다. https://github.com/wjdwndtlr/react-site/blob/master/front/pages/board.js front=>reducers/post.js https://github.com/wjdwndtlr/react-site/blob/master/front/reducers/post.js front=>sagas=> post.js https://github.com/wjdwndtlr/react-site/blob/master/front/sagas/post.js back=>routes => posts.js https://github.com/wjdwndtlr/react-site/blob/master/back/routes/posts.js _app https://github.com/wjdwndtlr/react-site/blob/master/front/pages/_app.js 현재 상태는 1~4번을 한번 눌렀을때 url이 NaN으로 나온다는것과 ( 두번누르면 제대로 나옵니다.) 리액트데브툴즈에서 데이터를 성공적으로 불러왔지만 1~4번을 눌러도 계속 똑같은 데이터를 불러오고 화면에 게시글출력이 똑같습니다. 질문을 썜이 더 보기좋게 하고싶었지만 이게 최선이였습니다. 링크를 타고 깃허브로 가야한다는 번거로움이 있지만요 ㅠㅠ 사실 이 글을 쓰기까지 세네번 질문을 올렸다 삭제했었습니다. 이유는 혼자했을때 잘안되면 바로 남에게 도움을 요청하는거같고, 너무 남의 도움에 의존하는거같아 혼자 해결하려했습니다..만 삼일이란 시간동안 하루 일곱시간 이상씩 붙잡고했지만 잘 안되어서 이정도면 충분히 시도해봤다싶어서 도움요청합니다...부탁드려요!! ㅠ ㅠ
- React로 NodeBird SNS 만들기
오류역에 봉착했어요
삭제된 글입니다
- 미해결React로 NodeBird SNS 만들기
팔로워 목록 삭제 기능 구현 중 질문드립니다.
1. 팔로워 삭제를 클릭하면, saga에서 removeFollowerAPI 함수에 진입하는걸 콘솔로 확인했습니다. 2. 네트워크에서 확인하면 pending이었다가, failed가 됩니다. 3. 서버 라우터에는 아예 진입을 하지 않습니다. 서버쪽 콘솔 Executing (default): SELECT `User`.`id`, `User`.`nickname`, `User`.`userId`, `User`.`password`, `User`.`createdAt`, `User`.`updatedAt`, `Posts`.`id` AS `Posts.id`, `Followings`.`id` AS `Followings.id`, `Followings->Follow`.`createdAt` AS `Followings.Follow.createdAt`, `Followings->Follow`.`updatedAt` AS `Followings.Follow.updatedAt`, `Followings->Follow`.`followingId` AS `Followings.Follow.followingId`, `Followings->Follow`.`followerId` AS `Followings.Follow.followerId`, `Followers`.`id` AS `Followers.id`, `Followers->Follow`.`createdAt` AS `Followers.Follow.createdAt`, `Followers->Follow`.`updatedAt` AS `Followers.Follow.updatedAt`, `Followers->Follow`.`followingId` AS `Followers.Follow.followingId`, `Followers->Follow`.`followerId` AS `Followers.Follow.followerId` FROM `Users` AS `User` LEFT OUTER JOIN `Posts` AS `Posts` ON `User`.`id` = `Posts`.`UserId` LEFT OUTER JOIN ( `Follow` AS `Followings->Follow` INNER JOIN `Users` AS `Followings` ON `Followings`.`id` = `Followings->Follow`.`followingId`) ON `User`.`id` = `Followings->Follow`.`followerId` LEFT OUTER JOIN ( `Follow` AS `Followers->Follow` INNER JOIN `Users` AS `Followers` ON `Followers`.`id` = `Followers->Follow`.`followerId`) ON `User`.`id` = `Followers->Follow`.`followingId` WHERE `User`.`id` = 2; Executing (default): SELECT `User`.`id`, `User`.`nickname`, `User`.`userId`, `User`.`password`, `User`.`createdAt`, `User`.`updatedAt`, `Posts`.`id` AS `Posts.id`, `Followings`.`id` AS `Followings.id`, `Followings->Follow`.`createdAt` AS `Followings.Follow.createdAt`, `Followings->Follow`.`updatedAt` AS `Followings.Follow.updatedAt`, `Followings->Follow`.`followingId` AS `Followings.Follow.followingId`, `Followings->Follow`.`followerId` AS `Followings.Follow.followerId`, `Followers`.`id` AS `Followers.id`, `Followers->Follow`.`createdAt` AS `Followers.Follow.createdAt`, `Followers->Follow`.`updatedAt` AS `Followers.Follow.updatedAt`, `Followers->Follow`.`followingId` AS `Followers.Follow.followingId`, `Followers->Follow`.`followerId` AS `Followers.Follow.followerId` FROM `Users` AS `User` LEFT OUTER JOIN `Posts` AS `Posts` ON `User`.`id` = `Posts`.`UserId` LEFT OUTER JOIN ( `Follow` AS `Followings->Follow` INNER JOIN `Users` AS `Followings` ON `Followings`.`id` = `Followings->Follow`.`followingId`) ON `User`.`id` = `Followings->Follow`.`followerId` LEFT OUTER JOIN ( `Follow` AS `Followers->Follow` INNER JOIN `Users` AS `Followers` ON `Followers`.`id` = `Followers->Follow`.`followerId`) ON `User`.`id` = `Followers->Follow`.`followingId` WHERE `User`.`id` = 2; DELETE /api/user/1/follower - - ms - - DELETE /api/user/1/follower - - ms - - 4. 어떻게 해결 해야 될까요?.. function removeFollowerAPI(userId) { console.log("saga removeFollowerAPI 요청 함수, userId > ", userId); return axios.delete(`/user/${userId}/follower`, { withCredentials: true }); } function* removeFollower(action) { try { const result = yield call(removeFollowerAPI, action.data); yield put({ type: REMOVE_FOLLOWER_SUCCESS, data: result.data }); } catch (e) { console.error(e); yield put({ type: REMOVE_FOLLOWER_FAILURE, error: e }); } } router.delete("/:id/follower", isLoggedIn, async (req, res, next) => { console.log("@@@@@@@@@@@@@@@@@@@@ /:id/follower delete"); try { const me = await db.User.findOne({ where: { id: req.user.id } }); await me.removeFollower(req.params.id); res.send(req.params.id); } catch (e) { console.error(e); next(e); } });
- 미해결React로 NodeBird SNS 만들기
질문있습니다.
강의에서나오는 프론트 server.js 코드중에서 server.get("/user/:id", (req, res) => { return app.render(req, res, "/user", { id: req.params.id }); }); server.get("/user/:id", 이부분이 back에서 routes get(/user/:id) 로 들어가는건가요? return app.render(req, res, "/user", { id: req.params.id }); 이 부분에서 /user는 프론트의 pages/user로 랜더 되는거구요? 즉 백엔드 라우터 /user/:id 로 경로 요청이들어와서 데이터를 처리해준후 데이터를 프론트pages/user로 랜더해준다는 뜻인가요?
- 미해결React로 NodeBird SNS 만들기
강의 깃허브 코드에 버그가 있습니다
어제 인피니트 스크롤링에서 버그가 발생한다고 글을 올렸습니다. 확인해보니 강의 코드에도, nodebird.com 에도 동일한 버그가 존재하지만 두 가지 버그가 맞물려 그런 현상이 일어나지 않는 것 처럼 보입니다. 우선 getInitialProps에서 한 번, onScroll 이벤트에서 한 번, 이렇게 총 두 번씩 request - request - success - success 하여 mainPosts에 중복된 데이터가 들어가는 현상은 사이트 내 스크롤바가 어느정도 아래로 내려와있는 상태에서, 포스트들을 로드하는 다른 페이지(index, hashtag, profile)로 이동했을 때, 해당 포스트들을 로딩하는 리퀘스트를 saga에서 throttle로 받게끔 한 경우 생깁니다. 노드버드 사이트 내에서는 버그를 재현하기가 굉장히 애매합니다. 노드버드 코드에서 throttle을 적용한 곳이 watchLoadMainPosts() 밖에 없습니다. 근데 index 페이지로 이동하는 버튼은 최상단에 있습니다. 그러니 스크롤바가 내려간 상태에서 인덱스 페이지로 이동하는 방법은 다른 페이지에서 스크롤을 쭉 내린 후 뒤로가기를 통해 들어가는 방법인데요, 이게 또 브라우저에 달린 뒤로가기 버튼으로는 발생하지 않고 마우스에 달린 뒤로가기 버튼이나 마우스 제스쳐를 통한 뒤로가기시에만 발생합니다ㅜㅜ.. 혹시 테스트 해보실 예정이라면 index 페이지 대신 watchLoadHashtagPosts() 코드를 throttle로 수정한 뒤에, 메인 페이지 스크롤을 쭉 내린 후 보이는 아무 해시태그나 눌러서 그 페이지로 들어가 확인하는게 더 편할 것 같습니다. 아무튼 저렇게 뒤로가기를 해서 메인 페이지로 돌아가게 되면 노드버드 페이지 콘솔에 다음과 같은 에러 로그가 찍힙니다. 이 부분은 https://github.com/ZeroCho/react-nodebird/blob/master/ch8/front/pages/index.js 해당 코드의 16번째 줄에서 mainPosts가 비어있는지 확인하지 않아 mainPosts가 비어있는 경우, undefined.id에 접근을 해서 나는 에러입니다. 페이지로 들어갈 때 getInitialProps에서 한 번, onScroll 이벤트에서 한 번씩 디스패치를 하게 되는데, getInitialProps에서 디스패치된 리퀘스트가 리덕스 state의 mainPosts를 빈 배열로 만들고, 그 상황에서 16번째 줄이 실행되어 위에 첨부한 에러가 발생합니다. 따라서 nodebird.com 내에선 해당 에러가 catch되어 아랫부분의 dispatch가 실행되지 않아 같은 포스트들이 두 번 로드되는 상황이 일어나지 않습니다. 결과적으로 사이트 내에선 버그가 없는 것 처럼 보익 ㄱㅔ됩니다. 실제로 제로초님 깃허브 코드를 그대로 받아 undefined 버그를 해결해 테스트해보면 중복된 데이터가 들어오는 현상이 일어납니다. 중복 데이터 버그를 해결하여 공지로 올려주시거나 강의에서 throttle 쓰는 내용을 제거하는게 좋을 것 같습니다. 감사합니다.
- 미해결React로 NodeBird SNS 만들기
질문입니다.
aws backend쪽에서 mysql설치하는 부분은 있던데 데이터 베이스 만드는 부분이 강좌에 있었나요?
- 미해결React로 NodeBird SNS 만들기
인피니트 스크롤링 버그 질문입니다
현재 "7-11 프론트 단에서 리덕스 액션 호출 막기" 강의까지 진행했습니다. 영상대로 하니 스크롤 이벤트에서 여러번 리퀘스트하는 현상은 해결 되었습니다. 근데 메인 포스트에서 해시태그를 눌러 "localhost/hashtag/태그" 경로로 연결되는 순간, 각각 getInitialProps에서 한 번, onScroll 이벤트에서 한 번씩 load hashtag posts request를 디스패치하고, 두 리퀘스트가 모두 success되어 중복된 포스트가 받아집니다.(saga 에선 throttle을 이용해 받았습니다) 이를 후반부 강의에서 해결하는지, 아니라면 어떻게 해결할 수 있을지 궁금합니다! pages/hashtag.js 코드는 아래와 같습니다.
- 해결됨React로 NodeBird SNS 만들기
multer 업로드 질문입니다.
안녕하세요. 오랜만에 질문드립니다. multer로 파일 업로드시에 직전에 올린 파일과 같은 파일을 연속해서 업로드 하면 원래 업로드가 되지 않는건가요? 예들 들면 a파일, a파일 의 순서로 하나씩 업로드하면 올라가지 않는데 a, b, a 의 순서로 하면 업로드가 잘 되더라구요. 혹시 해결방법이 있을까요?!