메인 화면의 가운데 부분에 해당하는 Feed 컴포넌트를 구현하고자 한다. 이 Feed 컴포넌트 안에는 InputOption과 Post 컴포넌트가 존재한다.
Feed 컴포넌트를 구현하기 위해서는 2가지 기능이 필요하다.
1) Input부분에 글을 작성하면, 작성자의 정보와 작성한 글이 DB에 저장되어야 한다. 이 때 DB는 Firebase를 활용한다.
2) 메인화면을 실행하면, 그동한 작성한 Post들을 불러와 Feed 부분에 띄워주어야 한다. Feed 컴포넌트 실행 시 작동하므로, React Hook 중 useEffect를 사용하도록 한다.
우선은 Feed.js를 구현한다.
import React, { useState, useEffect } from 'react'
import './Feed.css'
import CreateIcon from '@material-ui/icons/Create'
import InputOption from './InputOption'
import ImageIcon from '@material-ui/icons/Image'
import SubscriptionsIcon from '@material-ui/icons/Subscriptions'
import EventNoteIcon from '@material-ui/icons/EventNote'
import CalendarViewDayIcon from '@material-ui/icons/CalendarViewDay'
import Post from './Post'
import { db } from './firebase'
import firebase from 'firebase'
import { useSelector } from 'react-redux'
import { selectUser } from './features/userSlice'
import FlipMove from "react-flip-move"
function Feed() {
//Redux에 저장된 user 정보를 Selectorfh 가져온다
const user = useSelector(selectUser);
//Input 창에 작성한 글을 관리할 State
const [input, setInput] = useState('');
//DB에 저장된 글들을 불러오기 위한 State
const [posts, setPosts] = useState([]);
//DB에 저장된 Post를 불러오는 부분. 추후에 자세히 설명
useEffect(()=>{
db.collection("posts").orderBy('timestamp', 'desc').onSnapshot((snapshot)=>
setPosts(
snapshot.docs.map((doc)=>({
id: doc.id,
data: doc.data()
}))
)
);
},[]);
//Input 부분에 글을 작성하면, 그 내용을 저장하는 함수
const sendPost = e => {
e.preventDefault();
//Firebase의 DB를 세팅. firebase.js 참조
//DB 중에서 posts라는 collection에 작성한 글 저장
db.collection("posts").add({
//작성한 사람이 누구인지, 그리고 글내용, 마지막으로 작성한 시간까지 함께 저장
name: user.displayName,
description: user.email,
message: input,
photoUrl: user.photoUrl || "",
timestamp: firebase.firestore.FieldValue.serverTimestamp()
});
setInput("");
};
return (
//Feed 부분 전체를 담는 Div
<div className="feed">
//글을 작성할 수 있는 Input 부분
<div className="feed__inputContainer">
<div className="feed__input">
//Material UI로 아이콘을 완성
<CreateIcon />
<form>
//Input 창에 글을 작성하면, 그 내용을 Input 창에 바로 확인가능
<input type="text" value={input} onChange={e=>setInput(e.target.value)} />
//Send 버튼을 누르면 작성한 글을 저장하는 함수 실행
<button type="submit" onClick={sendPost}>Send</button>
</form>
</div>
//Input 창 밑에 있는 상세 메뉴들
<div className="feed__inputOptions">
//메뉴 아이콘과 메뉴명을 InputOption으로 보냄
//HeaderOption과 똑같음
<InputOption Icon={ImageIcon} title="Photo" color="#70B5F9" />
<InputOption Icon={SubscriptionsIcon} title="Video" color="#E7A33E" />
<InputOption Icon={EventNoteIcon} title="Event" color="#C0CBCD" />
<InputOption Icon={CalendarViewDayIcon} title="Write article" color="#7FC15E" />
</div>
</div>
//지금까지 작성한 글(post)를 보여주는 부분. 추후에 자세히 설명
<FlipMove>
{
posts.map(({id, data:{name, description, message, photoUrl}})=>(
<Post
key={id}
name={name}
description={description}
message={message}
photoUrl={photoUrl}
/>
))
}
</FlipMove>
</div>
)
}
export default Feed
Feed.js를 작성하였는데, Feed 컴포넌트 중에서도 글을 작성하는 기능을 우선 구현하였다. 글을 작성하면, 입력한 내용을 Input 창에서 바로바로 확인할 수 있도록 State를 사용하였다. 그리고 글을 작성한 뒤, 버튼을 누르면, 작성자가 누구인지와 함께 글의 내용을 DB에 저장할 수 있도록 Event Handling을 하였다. 이 때 DB는 Firebase 세팅 시 설정한 것이다.
Input창의 완성을 위해 InputOption.js도 작성한다.
import React from 'react'
import './InputOption.css'
function InputOption({Icon, title, color}) {
return (
<div className="inputOption">
//앞서 전달받은 아이콘과 메뉴명을 데이터바인딩한다
<Icon style={{color:color}} />
<h4>{title}</h4>
</div>
)
}
export default InputOption
'Projects > React + Firebase 링크드인 클론' 카테고리의 다른 글
#8. 위젯 부분 구현 | Widgets.js (0) | 2021.05.31 |
---|---|
#7. 저장한 글들을 피드에 띄워주기 | Post.js (0) | 2021.05.31 |
#5. 메인화면 및 사이드바 구현 | Sidebar.js (0) | 2021.05.31 |
#4. 로그인 부분 구현 | Login.js (0) | 2021.05.31 |
#3. Firebase와 Redux 설정 | firebase, store, userSlice (0) | 2021.05.31 |