Chinese (Simplified) (中文(简体)) translation by Zuojianzifu 作茧自缚 (you can also view the original English article)
在本系列教程的前一部分中,您了解了如何实现注册和登录功能。在本教程的这一部分中,您将实现用户主页以及添加和显示博客帖子的功能。
开始
让我们从本教程的第一部分克隆源代码开始吧。
https://github.com/royagasthyan/ReactBlogApp-SignUp
克隆目录后,导航到项目目录并安装所需的依赖关系。
cd ReactBlogApp-SignUp npm install
启动Node.js服务器,您将使应用程序在http:// localhost:7777/index.html#/上运行
创建用户主页
一旦用户尝试登录应用程序,您需要验证用户凭据,如果有效,则创建一个会话。要在Node.js应用程序中使用会话,您需要使用Node包管理器(npm)安装express-session
。
npm install express-session --save
在app.js
文件中引入express-session
。
var session = require('express-session');
要使用会话,您首先需要设置会话密钥。
app.use(session({secret: 'my-secret'}));
现在在全局范围中定义一个名为sessions
的变量。
var sessions
使用request参数在/signin
方法中指定sessions
变量。
sessions=req.session;
使用会话
变量,可以将登录的用户名保留在会话中。
sessions.username = user_name;
在应用程序的html
文件夹内创建名为home.html
的文件。他看起来是这样的:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>React Blog App</title> <link href="bootstrap.min.css" rel="stylesheet"> <link href="jumbotron-narrow.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="header clearfix"> <nav> <ul class="nav nav-pills pull-right"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Add</a></li> <li role="presentation"><a href="#">Logout</a></li> </ul> </nav> <h3 class="text-muted">React Blog App</h3> </div> <div class="jumbotron"> <div class="list-group"> <a href="#" class="list-group-item active"> <h4 class="list-group-item-heading">List group item heading</h4> <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> <a href="#" class="list-group-item"> <h4 class="list-group-item-heading">List group item heading</h4> <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> <a href="#" class="list-group-item"> <h4 class="list-group-item-heading">List group item heading</h4> <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> </div> </div> <footer class="footer"> <p>© 2016 Company, Inc.</p> </footer> </div> </body> </html>
创建一个名为/home
的路由,它将呈现有效用户的主页。
app.get('/home', function (req, res) { if(sessions && sessions.username){ res.sendFile(__dirname + '/html/home.html'); } else{ res.send('unauthorized'); } })
如上面的代码所示,当用户重定向到/home
路由时,如果sessions
和session.username
存在,则会渲染主页。
修改signin
方法以在验证用户成功时发送成功响应。
app.post('/signin', function (req, res) { sessions=req.session; var user_name=req.body.email; var password=req.body.password; user.validateSignIn(user_name,password,function(result){ if(result){ sessions.username = user_name; res.send('success'); } }); })
上述成功响应由React进行解析,如果成功,用户将被重定向到/home
路径。在main.jsx
文件中,在Signin
组件内部的SignIn
方法内,修改代码以重定向到主页。
signIn(){ axios.post('/signin', { email: this.state.email, password: this.state.password }) .then(function (response) { if(response.data == 'success'){ window.location.assign('http://localhost:7777/home') } }) .catch(function (error) { console.log(error); }); }
保存上述更改并重新启动Node服务器。使用有效的用户名和密码登录,您将被重定向到主页。

将上述博客通过使用React组件进行展示。创建一个名为home.jsx
的文件。在home.jsx
文件中创建一个名为ShowPost
的React组件,它将呈现博客文章列表。 移动静态的HTML页面至React组件的渲染方法中。ShowPost
React组件如下所示:
class ShowPost extends React.Component { constructor(props) { super(props); } render() { return ( <div className="list-group"> <a href="#" className="list-group-item active"> <h4 className="list-group-item-heading">List group item heading</h4> <p className="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> <a href="#" className="list-group-item"> <h4 className="list-group-item-heading">List group item heading</h4> <p className="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> <a href="#" className="list-group-item"> <h4 className="list-group-item-heading">List group item heading</h4> <p className="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> </div> ) } }
修改home.html
页面以包含所需的React库。以下是修改后的home.html
页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>React Blog App</title> <link href="bootstrap.min.css" rel="stylesheet"> <link href="jumbotron-narrow.css" rel="stylesheet"> <script src="https://fb.me/react-15.1.0.js"></script> <script src="https://fb.me/react-dom-15.1.0.js"></script> <script src="https://npmcdn.com/react-router@3.0.2/umd/ReactRouter.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="https://unpkg.com/babel-core@5.8.38/browser.min.js"></script> </head> <body> <div class="container"> <div class="header clearfix"> <nav> <ul class="nav nav-pills pull-right"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Add</a></li> <li role="presentation"><a href="#">Logout</a></li> </ul> </nav> <h3 class="text-muted">React Blog App</h3> </div> <div id="app" class="jumbotron"> </div> <footer class="footer"> <p>© 2016 Company, Inc.</p> </footer> </div> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script type="text/babel" src="home.jsx"> </script> </body> </html>
如上述HTML代码所示,容器div已被命名为app
,其中将显示React组件。
保存上述更改并重新启动Node服务器。登录博客应用程序,打开主页后,将显示ShowPost
React组件。
现在,您需要动态填充帖子列表中的值。在这之前,让我们创建一个页面来添加一个帖子。点击上面的Add
超链接,显示添加博客文章的页面。
添加帖子React组件
我们创建一个添加帖子的React组件来添加博客帖子。它将包括标题输入框和主题文本区域。在home.jsx
中,创建一个AddPost
React组件来添加博客帖子。以下是AddPost
React组件的代码:
class AddPost extends React.Component { render() { return ( <div className="col-md-5"> <div className="form-area"> <form role="form"> <br styles="clear:both" /> <div className="form-group"> <input type="text" className="form-control" id="title" name="title" placeholder="Title" required /> </div> <div className="form-group"> <textarea className="form-control" type="textarea" id="subject" placeholder="Subject" maxlength="140" rows="7"></textarea> </div> <button type="button" id="submit" name="submit" className="btn btn-primary pull-right">Add Post</button> </form> </div> </div> ) } }
当用户输入标题和帖子主题时,您需要处理React组件中的文本变化事件。将以下文本变化事件处理程序添加到AddPost
React组件。
handleTitleChange(e){ this.setState({title:e.target.value}) } handleSubjectChange(e){ this.setState({body:e.target.value}) }
在AddPost
添加变化监听事件来渲染HTML。
<div className="form-group"> <input type="text" onChange={this.handleTitleChange} className="form-control" id="title" name="title" placeholder="Title" required /> </div> <div className="form-group"> <textarea className="form-control" onChange={this.handleSubjectChange} type="textarea" id="subject" placeholder="Subject" maxlength="140" rows="7"></textarea> </div>
在React构造函数函数中绑定状态变量和事件。
constructor(props) { super(props); this.handleTitleChange = this.handleTitleChange.bind(this); this.handleSubjecChange = this.handleSubjectChange.bind(this); this.state = { title:'', subject:'' }; }
当用户点击Add Post
按钮时,您需要将标题和主题从React用户界面发布到Node.js后端,将其保存在MongoDB数据库中。 在AddPost
React组件中创建一个名为addPost
的方法来发布标题和主题文本到Node.js请求处理程序。 AddPost
React组件中的addPost
方法如下:
addPost(){ axios.post('/addPost', { title: this.state.title, subject: this.state.subject }) .then(function (response) { console.log('response from add post is ',response); hashHistory.push('/') }) .catch(function (error) { console.log(error); }); }
如上面的代码所示,您已经使用axios
将博客文章的详细信息发布到Node.js服务器
现在,您需要创建一个博客处理模块,用来处理添加和获取博客的详细信息。在项目目录中创建一个名为post.js
的文件。 在post.js
文件中,导出一个addPost
方法,该方法将把详细信息插入到MongoDB数据库中。引入MongoClient
并创建addPost
方法,以便在MongoDB数据库中插入详细信息。这是post.js
文件的代码:
var MongoClient = require('mongodb').MongoClient; var assert = require('assert'); var url = 'mongodb://localhost:27017/Blog'; module.exports = { addPost: function(title, subject, callback){ MongoClient.connect(url, function(err, db) { db.collection('post').insertOne( { "title": title, "subject": subject },function(err, result){ assert.equal(err, null); console.log("Saved the blog post details."); if(err == null){ callback(true) } else{ callback(false) } }); }); } }
如上面的代码所示,使用连接器连接到MongoDB数据库并插入了一条记录。执行操作后,开始检查是否有错误,并将状态返回给回调函数。
在app.js
文件的内部,创建一个名为addPost
的请求处理程序,它将从post.js
调用addPost
方法。看起来如下所示:
app.post('/addpost', function (req, res) { var title = req.body.title; var subject = req.body.subject; post.addPost(title, subject ,function(result){ res.send(result); }); })
保存上述更改并重新启动Node.js服务器。登录到应用程序,单击Add链接,并输入详细信息以添加帖子。完成后,单击“Add Post”按钮,这时帖子详情将保存在MongoDB数据库中。

展示帖子的React组件
首先,您需要从MongoDB中获取保存的帖子详情。在post.js
文件中,创建一个名为GetPost
的方法,该方法将提取文章详情。它看起来如下:
getPost: function(callback){ MongoClient.connect(url, function(err, db){ db.collection('post', function (err, collection) { collection.find().toArray(function (err, list) { callback(list); }); }); }) }
上述代码从MongoDB集合中获取详细信息,将其转换为列表,并将其发送到回调函数。 在home.jsx
文件中的ShowPost
组件中,在componentDidMount
方法中获取帖子的详细信息。如下所示:
componentDidMount(){ var self = this; axios.post('/getPost', { }) .then(function (response) { }) .catch(function (error) { console.log('error is ',error); }); }
上述代码向Node.js服务器方法/getPost
发送一个请求,该方法将在post.js
文件中调用getPost
方法。这是app.js
文件中的/getPost
方法。
app.post('/getpost', function (req, res) { post.getPost(function(result){ res.send(result); }); })
一旦文章详情在axios
回调中成功获取,请将详情保留在状态数组变量中。在ShowPost
构造函数中声明一个名为posts
的变量。
constructor(props) { super(props); this.state = { posts:[] }; }
在axios
的ajax回调成功成功时,设置状态变量如下所示:
self.setState({posts:response.data})
一旦发布了博客详情,您需要在React组件的渲染方法中动态创建所需的HTML。如下所示:
render() { return ( <div className="list-group"> { this.state.posts.map(function(post,index) { return <a href="#" key={index} className="list-group-item active"> <h4 className="list-group-item-heading">{post.title}</h4> <p className="list-group-item-text">{post.subject}</p> </a> }) } </div> ) }
上述代码迭代了posts
状态变量,并动态地创建了HTML。保存上述更改并重新启动Node.js服务器。 登录博客应用程序并使用主页上的Add按钮创建一些博客帖子。一旦帖子被添加,他们将显示在主页上。

结束语
在本教程中,您学习了如何创建用于添加和显示博客帖子的React组件。在本教程系列的下一部分中,您将学习如何添加删除和更新博客文章的功能。
让我在下面的评论部分中了解您对本教程的看法。本教程的源代码可在GitHub上找到。
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post