构建 React & Firebase 博客网站:第 2 部分
这篇文章最初发表在我的个人博客网站上。
欢迎回来!这是本系列文章的第二篇,将教您如何使用 React 和 Firebase 构建博客网站。如果您还没有阅读本系列的第一篇文章,我建议您阅读一下。我为这篇文章提供了初始代码,但您还需要完成上一篇文章中的以下步骤才能使用它:
- 步骤 1:注册 Firebase(如果您还没有帐户)
- 第 2 步:创建项目
- 步骤 5:向数据库添加数据
公平警告:由于这篇文章是基于第 1 部分撰写的,因此如果您密切关注本文,则假定您已经阅读过该文章。
目录
- 克隆(第 2 部分)启动代码 [可选]
- 添加创建帖子的页面
- 输入描述帖子的内容
- 编写创建函数
1. 克隆(第 2 部分)启动代码 [可选]
如果您已成功完成第 1 部分,请跳过此步骤。否则,您可以通过在终端中运行以下命令开始克隆代码:
git clone https://github.com/ashleemboyer/react-firebase-blog-starter-part-2.git
在继续之前,您需要更改一个文件:src/firebase.js
。如果打开它,您将看到以下config
常量:
const config = {
apiKey: "<YOUR-API-KEY>",
authDomain: "<YOUR-AUTH-DOMAIN>",
databaseURL: "<YOUR-DATABASE-URL>",
projectId: "<YOUR-PROJECT-ID>",
storageBucket: "<YOUR-STORAGE-BUCKET>",
messagingSenderId: "<YOUR-MESSAGE-SENDER-ID>",
appId: "<YOUR-APP-ID>"
};
常量中的属性用于将您的应用连接到 Firebase 项目。要查找这些值,请使用Firebase 控制台左侧边栏中的齿轮图标 ,转到您的项目设置。向下滚动到“您的应用”下的“Firebase SDK 代码段”,然后从它们调用的内容中复制属性firebaseConfig
。用这些值替换常量中的属性config
。
现在您可以运行npm install
并npm run start
在浏览器中查看您的项目。
2. 添加创建帖子的页面
您不必先执行此步骤。我只是按照首字母缩略词的顺序编写这些步骤。
要开始实现“创建帖子”功能,我们首先要创建一个用于创建帖子的页面。create.js
在 中添加一个文件src/pages
。为了确保一切正常运行,我们暂时将其保持在极简状态。
当您采取渐进的步骤并在整个过程中检查您的工作时,开发代码是最容易的。
我们的Create
组件现在会发出友好的“你好”。
import React from "react";
const Create = () => {
return <h1>Hello, from Create!</h1>;
};
export default Create;
尝试导航到该/create
页面。呃,哦……找不到该页面?
Route
别担心!我们只需要在 中为新页面添加一个src/App.js
。首先为组件添加一个导入Create
:
import Create from "./pages/create";
然后,Route
在路径下方添加以下内容/
:
<Route path="/create" component={Create} />
新的创建页面现在应该可以正常工作了!
3. 输入描述帖子的内容
现在,让我们思考一下实时数据库中的数据结构。以下每个属性都是我们用来描述博客文章的:
- 标题
- 蛞蝓
- 日期
- 封面图片
- 封面图片Alt
- 内容
考虑以下两个问题:我们需要为哪些属性创建<input>
for?哪些属性我们可以通过一些额外的代码自动生成?嗯……
如果我要为客户制作这个博客网站,我会自动生成slug
和date
。日期的自动生成并不难,但 slug 可能因为标点符号而变得复杂。我们这里不打算处理这个问题,但您可以自行尝试!此外,我可能会为 提供一个文件上传输入框coverImage
,但这也比我这篇博文想要描述的要复杂一些。
所以,date
是我们唯一要自动生成的。除了 之外,所有输入都会有content
, 会得到<textarea>
。让我们把所有这些输入都添加到我们的组件中,并使用 处理它们的值useState
。你的src/pages/create.js
文件应该如下所示:
如果你觉得这代码冗余了,那就太好了!(抱歉😅)我们会在“后续更新”的帖子里解决这个问题。
import React, { useState } from "react";
const labelStyles = {
display: "block",
marginBottom: 4
};
const inputStyles = {
width: "100%",
height: "2rem",
lineHeight: "2rem",
verticalAlign: "middle",
fontSize: "1rem",
marginBottom: "1.5rem",
padding: "0 0.25rem"
};
const Create = () => {
const [title, setTitle] = useState("");
const [slug, setSlug] = useState("");
const [coverImage, setCoverImage] = useState("");
const [coverImageAlt, setCoverImageAlt] = useState("");
const [content, setContent] = useState("");
const createPost = () => {
console.log({ title, slug, coverImage, coverImageAlt, content });
};
return (
<>
<h1>Create a new post</h1>
<section style={{ margin: "2rem 0" }}>
<label style={labelStyles} htmlFor="title-field">
Title
</label>
<input
style={inputStyles}
id="title-field"
type="text"
value={title}
onChange={({ target: { value } }) => {
setTitle(value);
}}
/>
<label style={labelStyles} htmlFor="slug-field">
Slug
</label>
<input
style={inputStyles}
id="slug-field"
type="text"
value={slug}
onChange={({ target: { value } }) => {
setSlug(value);
}}
/>
<label style={labelStyles} htmlFor="cover-image-field">
Cover image
</label>
<input
style={inputStyles}
id="cover-image-field"
type="text"
value={coverImage}
onChange={({ target: { value } }) => {
setCoverImage(value);
}}
/>
<label style={labelStyles} htmlFor="cover-image-alt-field">
Cover image alt
</label>
<input
style={inputStyles}
id="cover-image-alt-field"
type="text"
value={coverImageAlt}
onChange={({ target: { value } }) => {
setCoverImageAlt(value);
}}
/>
<label style={labelStyles} htmlFor="content-field">
Content
</label>
<textarea
style={{ ...inputStyles, height: 200, verticalAlign: "top" }}
id="content"
type="text"
value={content}
onChange={({ target: { value } }) => {
setContent(value);
}}
/>
<div style={{ textAlign: "right" }}>
<button
style={{
border: "none",
color: "#fff",
backgroundColor: "#039be5",
borderRadius: "4px",
padding: "8px 12px",
fontSize: "0.9rem"
}}
onClick={createPost}
>
Create
</button>
</div>
</section>
</>
);
};
export default Create;
您的页面现在看起来应该是这样的:
简单填写所有这些字段,看看点击“创建”按钮后会发生什么!你的控制台打开了吗?然后你应该会看到一个对象,里面打印了所有输入的值。我的控制台如下所示(点击展开):
4. 编写创建函数
太棒了!这就是我所说的代码增量修改。一步一步来。让我们进入激动人心的部分!我们要将一些内容发送回数据库。首先,我们需要从 导入我们的getFirebase
函数src/firebase.js
。
import { getFirebase } from "../firebase";
现在,添加generateDate()
函数,更新createPost
函数,并history
从Create
组件参数中解构 prop:
const generateDate = () => {
const now = new Date();
const options = { month: "long", day: "numeric", year: "numeric" };
const year = now.getFullYear();
let month = now.getMonth() + 1;
if (month < 10) {
month = `0${month}`; // prepend with a 0
}
const day = now.getDate();
if (day < 10) {
day = `0${day}`; // prepend with a 0
}
return {
formatted: `${year}-${month}-${day}`, // used for sorting
pretty: now.toLocaleDateString("en-US", options) // used for displaying
};
};
const createPost = () => {
const date = generateDate();
const newPost = {
title,
dateFormatted: date.formatted,
datePretty: date.pretty,
slug,
coverImage,
coverImageAlt,
content
};
getFirebase()
.database()
.ref()
.child(`posts/${slug}`)
.set(newPost)
.then(() => history.push(`/`));
};
const Create = ({ history }) => {
...
}
像我们几分钟前所做的那样填写您的输入,单击“创建帖子”,您将被带到主页,您的新帖子位于最顶部!
5.总结
呼!我以为我们能在一篇文章里讲完所有 4 个 CRUD 函数,但内容太多了。下一篇文章我们会继续讲解身份验证的探索之旅。目前为止,做得不错。💪
如果遇到任何问题或疑问,请给我发邮件或在推特上私信我!回头见!😊
你知道我有一份新闻通讯吗?📬
如果您想在我发布新博客文章或发布重大项目公告时收到通知,请访问https://ashleemboyer.com/newsletter。
鏂囩珷鏉ユ簮锛�https://dev.to/ashleemboyer/build-a-react-firebase-blog-site-part-2-2inm