用ReactJS和Python的Flask框架编写留言板的代码示例
作者:defshine 发布时间:2021-09-29 07:33:14
近期要在生产环境上使用react,所以,自己学习了一下,写了一个简单的留言板小程序。完整的代码可以到这里下载:message-board
Use
前端使用React,然后还有Bootstrap和jQuery,React负责前端展现,jQuery主要是向服务器发送ajax请求。
后端使用Flask和MongoDB,为前端提供数据。这里主要关注前端,对于后端不做过多说明。
使用webpack,对js文件进行打包。
About React
React是facebook开发一个用于前段交互的Javascript库。
刚刚开始使用,有这么几个特点:
1. 组件化开发。React提倡无状态的组件,便于重用。
2. VirtualDOM。React的性能比较高,得益于虚拟DOM。它不会每次都去直接操作DOM,因为操作DOM的代价是很大的,所以,它在内存中维护了虚拟DOM,通过计算虚拟DOM和浏览器上的DOM的变更进行操作。
3. 专注于View。React不是MVC框架,它只是一个专注于View的库,所以,它也可以和很多其他框架或者库一起使用。
4. 提供完成的生命周期。
Message Board
这个留言板小应用,主要有这样几个功能:
1.添加留言,一个表单:用户名和内容
2.列表展示,显示所有留言
3.简单的分页
Code
使用React,就要对应用进行组件的切分,尽量保持组件的无状态。
App
从宏观上组织整个应用,切分三个大组件:
1. MessageForm,添加留言表单。
2. MessageList,留言列表
3. Pager,留言的分页控制
当然,组件还可以继续划分。
子组件的数据都会回调到MessageBoard中,在这里统一控制。
MessageBoard.js
var React = require("react");
var MessageList = require("./MessageList");
var MessageForm = require("./MessageForm");
var Pager = require("./Pager");
var MessageBoard = React.createClass({
getInitialState : function(){
return {
messages: [],
page:0,
pages:0
}
},
submitMessage : function (author, content) {
$.ajax({
type:'post',
url:'/message',
data:{author:author,content:content}
}).done(function (data) {
console.log(data);
this.listMessage(1);
}.bind(this));
},
listMessage : function(page){
console.log("listMessages page:"+page)
$.ajax({
type:'get',
url:'/messages',
data:{page:page}
}).done(function (resp) {
if(resp.status == "success"){
var pager = resp.pager;
console.log(pager);
this.setState({
messages:pager.messages,
page:pager.page,
pages:pager.pages
});
}
}.bind(this));
},
componentDidMount : function(){
this.listMessage(1);
},
render : function(){
var pager_props = {
page : this.state.page,
pages : this.state.pages,
listMessage : this.listMessage
};
return(
<div>
<MessageForm submitMessage={this.submitMessage}/>
<MessageList messages = {this.state.messages}/>
<Pager {...pager_props}/>
</div>
)
}
});
module.exports = MessageBoard;
MessageForm
一个简单的表单,保存留言。用户提交后,数据会传给父组件。
MessageForm.js
var React = require("react");
var MessageForm = React.createClass({
handleSubmit : function (e) {
e.preventDefault();
var author = this.refs.author.getDOMNode().value.trim();
var content = this.refs.content.getDOMNode().value.trim();
this.props.submitMessage(author,content);
this.refs.author.getDOMNode().value = "";
this.refs.content.getDOMNode().value = ""
},
render : function(){
return(
<div className="well">
<h4>Leave a Message:</h4>
<div role="form">
<div className="form-group">
<input ref="author" className="form-control" placeholder="Name"/>
<textarea ref="content" className="form-control" rows="3" placeholder="Leave your message here"></textarea>
</div>
<a className="btn btn-primary" onClick={this.handleSubmit}>Submit</a>
</div>
</div>
)
}
});
module.exports = MessageForm;
MessageList
留言的列表展示,在写列表之前,把每条留言写成一个组件
Message.js
var React = require("react");
var Message = React.createClass({
render : function(){
var msg = this.props.message;
return(
<div>
<h3>{msg.author}
<small>{msg.time.toLocaleString()}</small>
</h3>
<p>{msg.content}</p>
</div>
)
}
});
module.exports = Message;
然后,再写列表.
数据从父组件通过props传递进来
MessageList.js
var React = require("react");
var Message = require("./Message");
var MessageList = React.createClass({
render : function () {
var messages = this.props.messages.map(function(item){
return <Message message={item}/>
});
console.log(messages);
return(
<div>
{messages}
</div>
)
}
});
module.exports = MessageList;
Pager
这是一个简单的分页,会显示当前页和总页数,还有上一页和下一页功能。
Pager.js
var React = require("react/addons");
var Pager = React.createClass({
getDefaultProps : function(){
return{
page:0,
pages:0
}
},
clickHandler: function(e){
e.preventDefault();
console.log(e.target.dataset.page);
console.log(e.target.dataset.page.value);
this.props.listMessage(e.target.dataset.page);
},
render : function(){
var cx = React.addons.classSet;
var preClass = cx({
'previous':true,
'disabled':this.props.page == 1
});
var nextClass = cx({
'next':true,
'disabled':this.props.page == this.props.pages
});
return(
<ul className="pager">
<li className={preClass} onClick={this.clickHandler}>
<a href="#" data-page={this.props.page-1}>←Prev</a>
</li>
<li>
<span>{this.props.page}/{this.props.pages}</span>
</li>
<li className={nextClass} onClick={this.clickHandler}>
<a href="#" data-page={this.props.page+1}>Next→</a>
</li>
</ul>
)
}
});
module.exports = Pager;
Summary
一个简单的小程序只能简单的感受一下React,这个库的思路和当前流行的库和框架相比,还是比较新颖的,值得学习~


猜你喜欢
- <%MaxPerPage=8 ’定义页面最大的记录数为8<br>
- 形态学处理,除了最基本的膨胀、腐蚀、开/闭运算、黑/白帽处理外,还有一些更高级的运用,如凸包,连通区域标记,删除小块区域等。1、凸包凸包是指
- 上节回顾主要讲了协程、进程、异步IO多路复用。 协程和IO多路复用都是单线程的。epoll 在linux下通过这个模块libev
- Pillow图片格式转换Pillow 库支持多种图片格式,您可以直接使用 open() 方法来读取图片,并且无须考虑图片是何种类型。Pill
- Python 面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将
- 问题近日在做一组声纹聚类时,使用了另一团队同学开发的声纹距离算法。该算法对外提供的是一组so包,需要使用方自己去使用。在python中调用纯
- 下面就来介绍一下这些在后台辛勤工作的进程们。系统检测器(System Monitor,SMON)、进程监视器(Process Monitor
- 什么是索引?哪些数据类型里有索引的概念? —> 字符串、列表、元组从最左边记录的位置开始就是索引索引用数字表示,起
- 前言Laravel 队列为不同的后台队列服务提供统一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其他基于关系
- 有过相关经验的朋友都知道,Jscript的效率毕竟有限,在数组中查找数据时如果用常规的算法来做执行起来会很慢。例如在一个含500个字符串的d
- 常用的消息摘要算法有MD5和SHA,这些算法在python和go的库中都有,需要时候调用下就OK了,这里总结下python和go的实现。一、
- 前言前段时间看到有人问如何使用Python实现多张图片组成文字的效果?觉得还挺有意思,于是尝试做了一下,刚好赶上端午节,所以打算从网上下载1
- 一、半同步简介MASTER节点在执行完客户端提交的事务后不是立刻返回结果给客户端,而是等待至少一个SLAVE节点接收并写到relay log
- Flappy Bird是前段时间(好像一年or两年前....)特别火的有一个小游戏,相信大家都玩过。Flappy Bird操作简单,通过点击
- setup.py:#!/usr/bin/env python# coding=utf-8from distutils.core import
- 本文实例讲述了Golang最大递减数算法问题。分享给大家供大家参考,具体如下:给出一个非负整数,找到这个非负整数中包含的最大递减数。一个数字
- 有朋友使用DIV居中,但是却发现DIV居中失灵了,是怎么回事呢?下面给大家解决一下问题,呵呵!1、一般情况下DIV居中失效是因为没写DTD语
- 1.MySQL中并发和隔离控制机制Meta-data元数据锁:在table cache缓存里实现的,为DDL(Data Definition
- 先来有用的use 数据库 update news set author='jb51' where author is nul
- #/bin/sh #检测mysql server是否正常提供服务 mysqladmin -u sky -ppwd -h localhost