44,000원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
direct messages에 접속상태는
어떻게하면 알 수 있나요? auth에서 정보를 가져오는 것인가요??
- 해결됨따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
31강의 ChatRoom 생성시 리액트모달 띄울때 에러가 나던데 왜 그런 걸까요 ? 작동은 잘 합니다.
31강의 ChatRoom 생성하기에 모달 팝업창에 질문 있습니다. 모달 팝업창을 띄우면 콘솔에 이런 에러가 나옵니다. Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node at div at Transition (http://localhost:3000/static/js/0.chunk.js:143095:30) at Fade (http://localhost:3000/static/js/0.chunk.js:66501:24) at BackdropTransition at Modal (http://localhost:3000/static/js/0.chunk.js:137780:24) at Modal (http://localhost:3000/static/js/0.chunk.js:67527:23) at div at ChatRooms (http://localhost:3000/static/js/main.chunk.js:999:5) at Connect(ChatRooms) (http://localhost:3000/static/js/0.chunk.js:139310:75) at div at SidePanel at div at div at ChatPage at Route (http://localhost:3000/static/js/0.chunk.js:142152:29) at Switch (http://localhost:3000/static/js/0.chunk.js:142354:29) at App (http://localhost:3000/static/js/main.chunk.js:182:84) at Router (http://localhost:3000/static/js/0.chunk.js:141787:30) at BrowserRouter (http://localhost:3000/static/js/0.chunk.js:141407:35) at Provider (http://localhost:3000/static/js/0.chunk.js:139023:20) 이런걸 찾아 보았는데, 제가 리액트 초보라 뭔말 인지 모르겠습니다. https://stackoverflow.com/questions/60903335/warning-finddomnode-is-deprecated-in-strictmode-finddomnode-was-passed-an-inst 검색을 해서 찾아본 페이지 입니다.
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
같은 값을 uid와 id에 두번 저장하는 이유는 무엇인가요?
chatRooms 데이터 베이스에 저장할때 생성한 key를 id컬럼에도 또 저장하는 이유가 무엇인가요??
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
firebase.auth().onAuthStateChanged()에 대해서 질문합니다.
안녕하세요. 항상 강의 잘보고 있습니다. 제 질문은 useEffect의 []안에 딱히 넣은 변수가 없어서 onAuthStateChanged는 한번만 실행된것 같은데 user가 바뀔때마다 바뀐 정보가 실시간으로 업데이트 되는 것인가요?? 어떻게 그게 가능한지 지금으로서는 잘 이해가 안되네요^^; onAuthStateChanged메소드 대신에 currentUser프로퍼티 사용하면 맨 처음 브라우저로 열었을때는 유저가 널로 오다가 두번째부터 그 전에 저장되어있던 유저가 오는데 그 이유는 무엇인지... onAuthStateChanged가 실시간 양방향 메소드라서 계속 통신하고 있는 거라면 어떤거는 실시간 양방향 통신을 하고 어떤거는 안하는데 어떻게 구분할 수 있는지 알 수 있을까요?? (죄송합니다ㅜ 머릿속이 혼란스러워 질문이 두서가 없네효...) 저는 Auth가 세션개념이라고 생각했는데.. 유저 전용 데이터베이스인가요??? 한번 로그인 하면 언제 다시 들어가도 유지 되는데 컴퓨터를 껏다 키면 로그인 정보 사라지게 할 순 없을까요?? ㅜ_ㅜ 또.. auth에 photoURL 업데이트하고 데이터베이스에 이미지URL 따로 저장하는 이유가 무엇인가요?? 이상입니다..
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
방생성자 생성시 DM 에서의 오류가 발생합니다
방생성자를 안쓰거나 하는 방법말고는 답이없는 부분이조?
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
안녕하세요 강사님 배포까지 다 완료해봤습니다.
그런데 제가 모바일에서도 잘작동하는지 한번 들어가봤는데 자꾸이런 화면이나와서 구글링을 하루 투자해서 온종일해도 찾을 수가 없네요 혹시해결방법을 알고 계실까요? 원인찾느라 너무 지치네요 ㅠㅠ
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
강사님 안녕하세요 강의 다시 처음부터 복습하려고 보고 있습니다!
그런데 아래와 같이 문구가 뜹니다. useEffect에서 history를 사용했을 때 console창에 아래와 같은 문구가 뜨는데 해결방법이 있을까요?? console.log창에서 아래와같이 문구가뜹니다. Line 26:6: React Hook useEffect has a missing dependency: 'history'. Either include it or remove the dependency array react-hooks/exhaustive-deps useEffect(() => { firebase.auth().onAuthStateChanged(user => { if (user) { history.push("/"); } else { history.push("/login"); } }) }, [])
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
let 변수가 아닌 useRef를 사용하는 이유가 있나요?
문득 궁금한데요, 그냥 let 변수가 아닌 useRef를 사용하는 이유가 있을까요?
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
clearUser()와 setUser(null)는 같은 거죠?
같다면 어떤 이유로 따로 만드는지 알 수 있을까요?
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
안녕하세요 강사님
10: 26초쯤에 chatroom.id를 [] 이렇게 배열안에다가 넣는 이유가 있을까요? 처음보는 거라서 궁금합니다!! else { usersRef .child(`${user.uid}/favorited`).update({ [chatRoom.id]: { name: chatRoom.name, description: chatRoom.description, createdBy: { name: chatRoom.createdBy.name, image: chatRoom.createdBy.image } } })
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
firebase database url 매핑
시켜줘야하는거 같은데 그냥 진행해도 되는건가요?
- 따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
함수형 컴포넌트 문제에 대해 질문있습니다.
삭제된 글입니다
- 해결됨따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
메시지 검색기능에서 match 함수
이전에 메시지 검색기능 구현하는 강의에서는 잘 실행이 됐는데 지금 다시 시도 해보면 오류가 납니다ㅠ 정규식과 일치하는지 확인하는 match함수에서 문제가 있는거 같은데 어떻게 해결해야 할지 몰라서 질문 올려 봅니다. ㅠㅠ 구글링을 통해서 찾아 봤을 때는 package-lock.json과 node_modules을 지우고 다시 npm을 설치 해보라 해서 시도 해봤는데 해결 되지 않았습니다. import React, { Component } from "react"; import Message from "./message"; import MessageHeader from "./message_header"; import MessageForm from "./message_form"; import styles from "./main_panel.module.css"; import { connect } from "react-redux"; import firebase from "../../../firebase"; import { setUserPosts } from "../../../redux/actions/chatRoom_action"; import Skeleton from "../../../commons/components/skeleton"; class MainPanel extends Component { messageEndRef = React.createRef(); state = { messagesRef: firebase.database().ref("messages"), messages: [], messageLoading: true, searchTerm: "", searchResults: [], searchLoading: false, typingRef: firebase.database().ref("typing"), typingUsers: [], listenersList: [], }; componentDidMount() { const { chatRoom } = this.props; if (chatRoom) { this.addMessageListener(chatRoom.id); this.addTypingListener(chatRoom.id); } } componentDidUpdate() { if (this.messageEndRef) { this.messageEndRef.scrollIntoView({ behavior: "smooth" }); } } componentWillUnmount() { this.state.messagesRef.off(); this.removeListeners(this.state.listenersList); } removeListeners = listeners => { listeners.forEach(listener => { listener.ref.child(listener.id).off(listener.event); }); }; addTypingListener = chatRoomId => { let typingUsers = []; this.state.typingRef.child(chatRoomId).on("child_added", DataSnapShot => { if (DataSnapShot.key !== this.props.user.uid) { typingUsers = typingUsers.concat({ id: DataSnapShot.key, name: DataSnapShot.val(), }); this.setState({ typingUsers }); } }); this.addToListenersList(chatRoomId, this.state.typingRef, "child_added"); this.state.typingRef.child(chatRoomId).on("child_removed", DataSnapShot => { const index = typingUsers.findIndex(user => user.id === DataSnapShot.key); if (index !== -1) { typingUsers = typingUsers.filter(user => user.id !== DataSnapShot.key); this.setState({ typingUsers }); } }); this.addToListenersList(chatRoomId, this.state.typingRef, "child_removed"); }; addToListenersList = (id, ref, event) => { //이미 등록된 리스너인가? const index = this.state.listenersList.findIndex(listener => { return ( listener.id === id && listener.ref === ref && listener.event === event ); }); if (index === -1) { const newListener = { id, ref, event }; this.setState({ listenersList: this.state.listenersList.concat(newListener), }); } }; handleSearchMessages = () => { const chatRoomMessages = [...this.state.messages]; const regex = new RegExp(this.state.searchTerm, "gi"); const searchResults = chatRoomMessages.reduce((acc, message) => { if ( (message.content && message.content.match(regex)) || message.user.name.match(regex) ) { acc.push(message); } return acc; }, []); this.setState({ searchResults }); setTimeout(() => this.setState({ searchLoading: false }), 1000); }; handleSearchChange = event => { console.log(event.target.value); this.setState( { searchTerm: event.target.value, searchLoading: true, }, () => this.handleSearchMessages() ); }; addMessageListener = chatRoomId => { let messagesArray = []; this.setState({ messages: [] }); this.state.messagesRef.child(chatRoomId).on("child_added", DataSnapShot => { console.log(DataSnapShot.val()); messagesArray.push(DataSnapShot.val()); this.setState({ messages: messagesArray, messageLoading: false, }); this.userPostCount(messagesArray); }); }; userPostCount = messages => { let usersPost = messages.reduce((acc, message) => { if (message.user.name in acc) { acc[message.user.name].count += 1; } else { acc[message.user.name] = { image: message.user.image, count: 1, }; } return acc; }, {}); this.props.dispatch(setUserPosts(usersPost)); }; renderMessages = messages => messages.length > 0 && messages.map(message => ( <Message key={message.timeStamp} message={message} user={this.props.user} /> )); renderTypingUsers = typingUsers => typingUsers.length > 0 && typingUsers.map(user => { return ( <span key={user.id}>{user.name}님이 채팅을 입력하고 있습니다.</span> ); }); renderMessageSkeleton = loading => loading && ( <> {[...Array(6)].map((e, idx) => ( <Skeleton key={idx} /> ))} </> ); render() { const { messages, searchResults, searchTerm, typingUsers, messageLoading, } = this.state; return ( <div className={styles.mainPanel}> <MessageHeader messages={messages} handleSearchChange={this.handleSearchChange} /> <div className={styles.messageBox}> {this.renderMessageSkeleton(messageLoading)} {searchTerm ? this.renderMessages(searchResults) : this.renderMessages(messages)} {this.renderTypingUsers(typingUsers)} <div ref={node => (this.messageEndRef = node)} /> </div> <MessageForm /> </div> ); } } const MapStateToProps = state => { return { user: state.user.currentUser, chatRoom: state.chatRoom.currentChatRoom, }; }; export default connect(MapStateToProps)(MainPanel);
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
안녕하세요!
안녕하세요 강사님 혹시 궁금한게 있는데 여기서 chatrooms.length >0 && 이걸 왜넣는지 궁금합니다. 빼고 넣어도 잘 렌더링되는데 넣어주는 이유가 있을까요? renderChatRooms = (chatRooms) => chatRooms.length > 0 && chatRooms.map(room => ( <li key={room.id} > # {room.name} </li> ))
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
메시지 컴포넌트를 만들때 key값이 왜 필요한지 이해가 안됩니다.
MainPanel의 key 와 firebase간의 관계가 있나요?
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
안녕하세요! 이 강의에서 다른 유저의 온오프라인 확인에 대해 질문있습니다
안녕하세요! 이 강의에서 다른 유저의 온오프라인을 확인할수 있는 빨간 점과 초록 점이 있는 것을 예제로 사용하시던데 그 부분은 강의에 포함되어있지 않은 것 같아서 질문 남깁니다. 강의에 포함이 원래 안되어 있는 부분인가요??
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
unexpected EOF.
이런 오류가 발생 합니다 ㅠ 잘못 쓴게 있나 유심히 봐도 보이지가 않습니다 { "rules": { "chatRooms" : { ".read" : "auth != null", "&chatRoomId" : { ".write" : "auth != null", ".validate" : "newData.hasChildren(['id','name', 'createdBy', 'description'])", "id": { ".validate" : "newData.val() === $chatRoomId" }, "name" : { ".validate" : "newData.val().length > 0" }, "description" :{ ".validate" : "newData.val().length > 0" } } }, "messages" : { ".read" : "auth !== null", ".write" : "auth !== null", "content": { ".validate" : "newData.val().length >0" }, "image" : { ".validate" : "newData.val().length >0" }, "user" : { ".validate" : "newData.hasChildren(['id','image','name'])" } }, "presence" : { ".read": "auth != null", ".write" : "auth != null" }, "typing" : { ".read": "auth != null", ".write": "auth != null" }, "users" :{ ".read" : "auth != null", "$uid" : { ".write" : "auth != null && auth.uid === $uid", ".validate" : "newData.hasChildren(['name','image'])", "name" : { ".validate" :"newData.val().length > 0" }, "image": { ".validate" : "newData.val().length > 0" } } } }
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
안녕하세요. 저는 함수형으로 코드를 짜고 있는데 질문있습니다.
밑 그림과 같이 componentDidMount() 라이프사이클을 대신하여, useEffect() 를 사용하려고하는데 감이 잘 잡히지 않네요... 빈 배열에 chatRooms state값을 넣어서 바뀔때마다 실행되게 해야하나 했더니 chatRoomsRef.on 속성때문에 계속 on 되어서 그런지 계속 무한 루프가 걸려서 과부하가 걸리더라고요..; 그렇게해서 저렇게 빈 속성을 넣게되면은 또 하나의 채팅방만 보이게됩니다 ㅠㅠ , 함수형으로 구현했을때 useEffect에 대해서 어떻게 사용해야 할지 감이 안오네요
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
회원 가입후 displayName이 제대로 표시 안되는 이슈 문의
안녕하세요. 회원 가입후 displayName이 제대로 표시 안되는 이슈 문의입니다. 회원 가입을 누르면 firebase의 createUserWithEmailAndPassword()을 통해서 회원 가입을 진행하는데요.이게 자동 로그인 이더라구요.자동 로그인 된후 app.js에 등록해 두었던 firebase의 onAuthStateChanged 콜백이 호출되고 여기서 리덕스를 통해 사용자 정보를 등록합니다.사이드바가 렌더링 되면서 리덕스에서 사용자 정보를 가져오는데 여기서 displayName과 photoURL이 표시가 안되네요.firebase에 displayName과 photoURL을 업데이트 하기 전에 onAuthStateChanged는 트리거되고사용자 정보가 업데이트 되더라도 onAuthStateChanged 콜백은 호출되지 않다보니 이런 현상이 일어난거 같고요. 새로고침하면 firebase에서 업데이트된 정보를 가져오므로 제대로 표시됩니다. 현재 4강까지 강의 들었는데 이 이슈에 대해 해결하는 부분이 있을까요? 구글링 해보니 자동 로그인을 막고 강제 로그아웃하라고 나와있어서 아래 링크 21L에서 강제 로그아웃 시키고 있습니다. https://github.com/sajacaros/react-chat/blob/main/src/components/RegisterPage/RegisterPage.js
- 미해결따라하며 배우는 리액트, 파이어베이스 - 채팅 어플리케이션 만들기[2023.12 리뉴얼]
directmessage에서..
열심히 수강 중에 있는데, 강의내용에는 빠졌지만, 보통 채팅 서비스에서 가장 많이 사용되는 부분이라, 어떻게 구현해야하는지 잘 몰라서 ㅠㅠ 질문 남겨봅니다. directmessage에서, a라는 사람이 b라는 사람에게 채팅을 시작하려고 할때, b라는 사람이 그 채팅을 수락할지 거절할지에 대한 모달창이 뜨는 걸 구현해보고 싶은데, 어떻게 구현해야하는지 알고 싶어요.. ㅠㅠ 약간의 팁이라거나 공부를 할 수 있는 힌트라도 주시면 너무 감사하겠습니다. 강의와 관련있는 질문을 남겨주세요.• 강의와 관련이 없는 질문은 지식공유자가 답변하지 않을 수 있습니다. (사적 상담, 컨설팅, 과제 풀이 등)• 질문을 남기기 전, 비슷한 내용을 질문한 수강생이 있는지 먼저 검색을 해주세요. (중복 질문을 자제해주세요.)• 서비스 운영 관련 질문은 인프런 우측 하단 ‘문의하기’를 이용해주세요. (영상 재생 문제, 사이트 버그, 강의 환불 등) 질문 전달에도 요령이 필요합니다.• 지식공유자가 질문을 좀 더 쉽게 확인할 수 있게 도와주세요.• 강의실 페이지(/lecture) 에서 '질문하기'를 이용해주시면 질문과 연관된 수업 영상 제목이 함께 등록됩니다.• 강의 대시보드에서 질문을 남길 경우, 관련 섹션 및 수업 제목을 기재해주세요. • 수업 특정 구간에 대한 질문은 꼭 영상 타임코드를 남겨주세요! 구체적인 질문일수록 명확한 답을 받을 수 있어요.• 질문 제목은 핵심 키워드를 포함해 간결하게 적어주세요.• 질문 내용은 자세하게 적어주시되, 지식공유자가 답변할 수 있도록 구체적으로 남겨주세요.• 정확한 질문 내용과 함께 코드를 적어주시거나, 캡쳐 이미지를 첨부하면 더욱 좋습니다. 기본적인 예의를 지켜주세요.• 정중한 의견 및 문의 제시, 감사 인사 등의 커뮤니케이션은 더 나은 강의를 위한 기틀이 됩니다. • 질문이 있을 때에는 강의를 만든 지식공유자에 대한 기본적인 예의를 꼭 지켜주세요. • 반말, 욕설, 과격한 표현 등 지식공유자를 불쾌하게 할 수 있는 내용은 스팸 처리 등 제재를 가할 수 있습니다.