Firebase 및 React로 나만의 좋아요 및 댓글 시스템을 구축하는 방법
31042 단어 tailwindcsstutorialfirebasereact
Cusdis와 Disqus는 CLS(Cumulative Layout Shift)에 큰 영향을 미치기 때문에 성능 친화적이지 않습니다.
그래서 나는 Firebase , TailwindCSS 및 React 으로 시스템을 만들기 시작했습니다. TailwindCSS는 강제는 아니지만 도서관에 가는 것입니다. 시작하자.
Firebase 설정
npm i firebase
// File: @/lib/firebase.js
import 'firebase/firestore'
import firebase from 'firebase/app'
// More about firebase config on https://firebase.google.com/docs/web/setup#config-object
var firebaseConfig = {
apiKey: '',
authDomain: '',
projectId: '',
storageBucket: '',
messagingSenderId: '',
appId: '',
}
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig)
} else {
firebase.app()
}
export const firestore = firebase.firestore()
export default firebase
유사 구성 요소 생성
// File: components/blog/like.js
import { firestore } from '@/lib/firebase'
export const getLikes = (slug, callBackFunction) => {
firestore
.collection('likes')
.doc(slug)
.get()
.then((doc) => {
if (doc.exists) {
callBackFunction(Object.keys(doc.data()).length)
}
})
.catch((err) => {
console.error(err)
})
}
export const postLike = (slug, callBackFunction) => {
fetch('https://api.ipify.org/?format=json', {
method: 'GET',
})
.then((res) => res.json())
.then((res) => {
firestore
.collection('likes')
.doc(slug)
.set(
{
[res['ip']]: null,
},
{ merge: true }
)
.then(callBackFunction)
})
.catch((err) => {
console.error(err)
})
}
코멘트 컴포넌트 생성
// File: components/blog/comments.js
import { useState } from 'react'
import firebase, { firestore } from '@/lib/firebase'
export const getComments = (slug, callBackFunction) => {
firestore
.collection('comments')
.get()
.then((snapshot) => {
const posts = snapshot.docs
.map((doc) => doc.data())
.filter((doc) => doc.slug === slug)
.map((doc) => {
return { id: doc.id, ...doc }
})
callBackFunction(posts)
})
.catch((err) => {
console.log(err)
})
}
export const writeComment = (name, slug, content, email, callBackFunction) => {
let temp = {
name,
slug,
content,
time: firebase.firestore.Timestamp.fromDate(new Date()),
}
if (email.length > 0) temp['email'] = email
firestore
.collection('comments')
.add(temp)
.then(() => {
callBackFunction()
})
.catch((err) => {
console.error(err)
})
}
export const LoadComments = ({ comments }) => {
return comments
.sort((a, b) =>
a.time.toDate().getTime() > b.time.toDate().getTime() ? -1 : 1
)
.map((item) => (
<div
key={item.time.seconds}
className="border dark:border-gray-500 rounded p-5 w-full mt-5 flex flex-col"
>
<span className="text-lg text-gray-500 dark:text-gray-300 font-medium">
{item.name} · {item.time.toDate().toDateString()}
</span>
<span className="mt-3 text-md text-gray-500 dark:text-gray-300">
{item.content}
</span>
</div>
))
}
const WriteComment = ({ slug, setComments }) => {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [comment, setComment] = useState('')
return (
<form
onSubmit={(e) => {
e.preventDefault()
writeComment(name, slug, comment, email, () =>
getComments(slug, setComments)
)
setName('')
setEmail('')
setComment('')
}}
className="mt-10 flex flex-col w-full"
>
<h1 className="font-semibold text-lg">Write a comment</h1>
<div className="flex flex-col sm:flex-row sm:space-x-5 items-start">
<input
required
value={name}
placeholder="Name*"
onChange={(e) => setName(e.target.value)}
className="mt-5 w-full sm:w-1/2 appearance-none outline-none ring-0 px-5 py-2 border dark:hover:border-white hover:border-black rounded hover:shadow text-black dark:bg-black dark:text-gray-300 dark:border-gray-500"
/>
<div className="mt-5 w-full sm:w-1/2 flex flex-col space-y-1">
<input
value={email}
placeholder="Email (Optional)"
onChange={(e) => setEmail(e.target.value)}
className="w-full appearance-none outline-none ring-0 px-5 py-2 border dark:hover:border-white hover:border-black rounded hover:shadow text-black dark:bg-black dark:text-gray-300 dark:border-gray-500"
/>
<span className="text-sm text-gray-400">
Email will remain confidential.
</span>
</div>
</div>
<textarea
required
value={comment}
onChange={(e) => setComment(e.target.value)}
placeholder={'Comment*\nMaximum of 500 characters.'}
className="mt-5 appearance-none outline-none ring-0 pt-5 px-5 pb-10 border dark:hover:border-white hover:border-black rounded hover:shadow text-black dark:bg-black dark:text-gray-300 dark:border-gray-500"
/>
<button
type="submit"
className="w-[200px] appearance-none mt-5 py-2 px-5 text-center rounded border hover:bg-gray-100 dark:hover:bg-[#28282B] dark:border-gray-500"
>
Post a comment
</button>
</form>
)
}
export default WriteComment
다이내믹 블로그 컴포넌트 생성
import WriteComment, {
getComments,
LoadComments,
} from '@/components/blog/comments'
export default function Post({ post }) {
const [comments, setComments] = useState([])
return <>
<WriteComment setComments={setComments} slug={post.slug} />
<div className="mt-10 pt-10 w-full border-t dark:border-gray-500">
<button
onClick={() => getComments(post.slug, setComments)}
className="w-[200px] appearance-none py-2 px-5 text-center rounded border hover:bg-gray-100 dark:hover:bg-[#28282B] dark:border-gray-500"
>
Load Comments
</button>
</div>
<LoadComments comments={comments} />
</>
}
예시
내 blog page에서 예를 볼 수 있습니다! 소스 코드를 사용할 수 있습니다here.
Reference
이 문제에 관하여(Firebase 및 React로 나만의 좋아요 및 댓글 시스템을 구축하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/reeshee/how-to-build-your-own-likes-and-comments-system-with-firebase-and-react-30o3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)