, December 05, 2021

0 kết quả được tìm thấy

Hướng dẫn clone instagram với React JS và Firebase phần 5.


  •   6 min reads
Hướng dẫn clone instagram với React JS và Firebase phần 5.

Ở phần 4, chúng ta đã cùng nhau setup Authentication cho app của của chúng ta. Trong phần 5 này, chúng ta sẽ sửa dụng tài khoản mà ta đã đăng ký trên app của mình để đăng những bài viết cũng như ảnh lên app instagram clone này, kèm theo các comment và lưu xuống database của firebase. Okie! không dài dòng nữa, chúng ta bắt đầu thôi 😁.

I. Tạo from upload ảnh và caption của bài post.

Ta sẽ tận dụng modal đã có sẵn từ modal Sign In vs Sign Up để tạo một modal upload bài post của chúng ta nhé 😁.

Trong App.js ta tạo thêm một modal như sau:

//State
const [openModalUpload, setOpenModalUpload] = useState(false);
const [image, setImage] = useState(null);
const [progress, setProgress] = useState(0);
const [caption, setCaption] = useState("");

const handleClickAddNewPost = (childData) => {
		setOpenModalUpload(childData);
};

//Modal
<Modal open={openModalUpload} onClose={() => setOpenModalUpload(false)}>
	<div style={modalStyle} className={classes.paper}>
		<form className="form__signup">
			<img className="form__logo"
		src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
							alt="Logo"
						/>
			<div className="form__group">
				<progress value={progress} max="100" />
			</div>
			<div className="form__group">
				<Input
					className="form__field"
					placeholder="Enter a caption"
					type="text"
					value={caption}
					onChange={(e) => setCaption(e.target.value)}
				/>
			</div>
			<div className="form__group">
				<input
					className="form__field"
					type="file"
					onChange={handleChangeFile}
				/>
			</div>
			<Button className="btn-signup" onClick={handleUpload}>
				Upload
			</Button>
		</form>
	</div>
</Modal>

Như vậy là ta đã setup xong cho phần modal để upload bài post rồi, tiếp theo ta setup việc khi ta Sign In rồi thì mới được tạo mới bài post. Trong phần Header.jsx ta thêm button để upload post như sau:

const transferMessageAddNewPost = () => {
	setAddNew(true);
	props.takeMessAddNewPost(addNew);
}
//JSX
<div className="header__login">
	{props.user ? (
		<>
			<Button className="btn btn-upload" onClick {transferMessageAddNewPost}>
				<i className='bx bx-message-square-add'></i>
			</Button>
			<Button onClick={transferMessageLogOut} className="btn btn-login">Log out</Button>
		</>) : (
			   <div>
			   		<Button onClick={transferMessageLogIn} className="btn btn-login">Sign in</Button>
					<Button onClick={transferMesageSignUp} className="btn btn-sign-up">Sign up</Button>
				</div>
	)}
					
</div>

Css cho button upload:

.btn-upload:hover {
	background-color: #fff !important;
}

.bx-message-square-add {
	font-size: 1.45rem;
	font-weight: 500;
	transition: all 0.5s ease;
}

.bx-message-square-add:hover {
	opacity: 0.8;
	text-shadow: 2px 4px 3px rgba(0,0,0,0.3);
}

Kết quả ta sẽ có được modal như hình:

II. Lưu bài post xuống database của firebase.

Trong App.js, ta thêm đoạn code như sau:

const handleUpload = () => {
		const uploadTask = storage.ref(`images/${image.name}`).put(image);

		uploadTask.on(
			"state_changed",
			(snapshot) => {
				//progress function
				const progress = Math.round(
					(snapshot.bytesTransferred / snapshot.totalBytes) * 100
				);
				setProgress(progress);
			},
			(error) => {
				//handle Error
				alert(error.message);
			},
			() => {
				//handle when complete
				storage.ref("images").child(image.name).getDownloadURL().then(
					url => {
						//Save link image in db of firebase
						db.collection('posts').add(
							{
								timestamp: firebase.firestore.FieldValue.serverTimestamp(),
								caption: caption,
								imageUrl: url,
								userName: username
							}
						);
						setProgress(0);
						setCaption('');
						setImage(null);
					}
				);
			}
		);
	};

Giải thích tý về đoạn code trên:

  • uploadTask: biến này để ta tham chiếu đến storage nơi lưu trữ image của chúng ta.
  • uploadTask.on(): Giúp ta theo giỏi quá trình upload một task lên firebase.
  • getDownloadURL(): Khi ta upload image lên firebase thì nó sẽ cho ta một link để sử dụng ảnh đó, dùng phương thức này để lấy link đó về và lưu vào trong docs của chúng ta.

Okie! Cùng test thử xem thế nào nhé 😁

Okie được luôn 😁

III. Thêm comment cho bài post.

Đầu tiên, UI của chúng ta đã có sẵn chỗ để ta comment luôn rồi hehe 😁. Ta tiến hành tạo collection cho các comment để test trước.

Chọn một bài post bất kỳ, sau đó click Start collection để tạo một collection comments trong bài post đó.

Bạn có thể nhập tên như hình hoặc tên nào bạn muốn cũng được, sau đó nhấn next.

Sau đó nó sẽ hiện ra bản như hình trên, theo thứ tự bạn click vào button Auto-ID để nó tự động sinh ID cho chúng ta, phần thứ 2 các bạn có thể nhập theo mình hoặc nhập sao thì tùy ý các bạn 😁, sau đó nhấn Save.

Trong file App.js ta thêm attribute postIduser cho component PostItem

<PostItem key={id} postId={id} user={user} data={post} />

Trong file PostItem.jsx ta thêm các dòng code sau:

import React, { useState, useEffect } from "react";
import { db } from "../../firebaseConfig";
import firebase from "firebase/compat";

//Sate
const [comments, setComments] = useState([]);
const [comment, setComment] = useState("");

useEffect(() => {
	let unSubscribe;
	if (props.postId) {
		unSubscribe = db
			.collection("posts")
			.doc(props.postId)
			.collection("comments")
			.onSnapshot((snapshot) => {
				setComments(
					snapshot.docs.map((doc) => ({
						id: doc.id,
						cmt: doc.data(),
					}))
				);
			});
	}
	return () => {
		unSubscribe();
	};
}, [props.postId]);

{/* list comment */}
<div className="post__comment--list">
	{comments.map(({ id, cmt }) => (
		<p key={id} className="post__comment--item">
			<b>{cmt.userName}</b> {cmt.comment}
		</p>
	))}
</div>
{/* input field for comment */}
<div className="post__comment">
	<form>
		<span>
			<i className="bx bx-smile"></i>
		</span>
		<input
			value={comment}
			type="text"
			placeholder="Thêm bình luận..."
			onChange={(e) => setComment(e.target.value)}
		/>
		<button
			type="submit"
			disabled={!comment}
			className="btn btn-post-comment"
		>
			Đăng
		</button>
	</form>
</div>

Một ít css cho list comment:

/* comment list */
.post__comment--list {
	padding: 0 16px;
}

.post__comment--list b {
	color: rgba(38, 38, 38, 0.85);
}

.post__comment--item {
	margin-bottom: 10px;
}

Okie, work ngon lành luôn 😁, tiếp theo chúng ta sẽ chức năng thêm các comment vào vài đăng lên bài post.

Trong PostItem.jsx ta, phần button đăng các comment ta thêm hàm onClick() như sau:

const submitComment = (e) => {
	e.preventDefault();
	db.collection("posts").doc(props.postId).collection("comments").add({
		comment: comment,
		userName: props.user.displayName,
		timestamp: firebase.firestore.FieldValue.serverTimestamp(),
	});
	setComment("");
};

<button
	type="submit"
	disabled={!comment}
	className="btn btn-post-comment"
	onClick={submitComment}
>
	Đăng
</button>

Xong, ta test thử xem thế nào nhé 😁.

Như vậy là chúng ta đã hoàn thành xong app instagram clone của chúng ta rồi 😁

IV. Tổng kết.

Như vậy sau 5 phần của series clone instagram với ReactJs và firebase, chúng ta đã hoàn thành xong app instagram clone đơn giản dành cho những bạn mới bắt đầu và làm quen với ReactJs, bonus thêm một ít kiến thức về firebase. Hy vọng qua series này sẽ giúp cho các bạn nắm được những căn bản về ReactJs.

Hẹn gặp lại các bạn trong những series về chủ để ReactJs tiếp theo nhé 🤗. See u again.

Bài viết cùng seri

Bài viết liên quan

Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 5

Trong phần 5 này, chúng ta sẽ hoàn thiện Guest Home Page và config để connect với firebase, chuẩn bị cho các phần tiếp theo nhé 😉....

Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 5
Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 4

Trong phần 4 của series này, chúng ta sẽ tiếp tục hoàn thiện phần Guest Home Page . Lần này, chúng ta sẽ bắt tay vào code phần FAQs component, thực hiện config router để redirects qua lại các page nhé. Cùng bắt đầu thôi 😉....

Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 4
Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 3

Tiếp tục công việc đang dang dở ở phần 2, trong phần 3 này chúng ta sẽ làm phần Footer ở Guest Home Page này, kèm theo đó chúng ta sẽ apply các tool như ESLint và Prettier vào project của chúng ta nhé....

Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 3
Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 2

Sau phần 1 của series này, chắc hẵn các bạn đã nóng lòng muốn bắt tay ngay vào code rồi đúng không 😁. Okie, trong phần thứ 2 của series này, chúng ta sẽ cùng nhau tạo phần Story của trang Home dành cho khách trên trang Netflix nhé (Trang lúc ta vào mà chưa login ấy 😁). Nào! bắt đâu thôi!...

Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 2
Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 1

Hello các bạn, hôm nay mình sẽ mang đến cho các bạn một series mới về chuyên mục ReactJS đó là series "Netflix Clone with ReactJS, Styled Components and Firebase (Firestore & Auth)". Trong phần đầu tiên của series này, chúng ta sẽ setup project của chúng ta trước nhé. Nào bắt đầu thôi 😉....

Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 1
You've successfully subscribed to 200Lab Blog
Great! Next, complete checkout for full access to 200Lab Blog
Xin chào mừng bạn đã quay trở lại
OK! Tài khoản của bạn đã kích hoạt thành công.
Success! Your billing info is updated.
Billing info update failed.
Your link has expired.