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