用ReactJS和Python的Flask框架編寫留言板的代碼示例
近期要在生產(chǎn)環(huán)境上使用react,所以,自己學(xué)習(xí)了一下,寫了一個(gè)簡單的留言板小程序。完整的代碼可以到這里下載:message-board
Use
前端使用React,然后還有Bootstrap和jQuery,React負(fù)責(zé)前端展現(xiàn),jQuery主要是向服務(wù)器發(fā)送ajax請(qǐng)求。
后端使用Flask和MongoDB,為前端提供數(shù)據(jù)。這里主要關(guān)注前端,對(duì)于后端不做過多說明。
使用webpack,對(duì)js文件進(jìn)行打包。
About React
React是facebook開發(fā)一個(gè)用于前段交互的Javascript庫。
剛剛開始使用,有這么幾個(gè)特點(diǎn):
1. 組件化開發(fā)。React提倡無狀態(tài)的組件,便于重用。
2. VirtualDOM。React的性能比較高,得益于虛擬DOM。它不會(huì)每次都去直接操作DOM,因?yàn)椴僮鱀OM的代價(jià)是很大的,所以,它在內(nèi)存中維護(hù)了虛擬DOM,通過計(jì)算虛擬DOM和瀏覽器上的DOM的變更進(jìn)行操作。
3. 專注于View。React不是MVC框架,它只是一個(gè)專注于View的庫,所以,它也可以和很多其他框架或者庫一起使用。
4. 提供完成的生命周期。
Message Board
這個(gè)留言板小應(yīng)用,主要有這樣幾個(gè)功能:
1.添加留言,一個(gè)表單:用戶名和內(nèi)容
2.列表展示,顯示所有留言
3.簡單的分頁
Code
使用React,就要對(duì)應(yīng)用進(jìn)行組件的切分,盡量保持組件的無狀態(tài)。
App
從宏觀上組織整個(gè)應(yīng)用,切分三個(gè)大組件:
1. MessageForm,添加留言表單。
2. MessageList,留言列表
3. Pager,留言的分頁控制
當(dāng)然,組件還可以繼續(xù)劃分。
子組件的數(shù)據(jù)都會(huì)回調(diào)到MessageBoard中,在這里統(tǒng)一控制。
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
一個(gè)簡單的表單,保存留言。用戶提交后,數(shù)據(jù)會(huì)傳給父組件。
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
留言的列表展示,在寫列表之前,把每條留言寫成一個(gè)組件
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;
然后,再寫列表.
數(shù)據(jù)從父組件通過props傳遞進(jìn)來
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
這是一個(gè)簡單的分頁,會(huì)顯示當(dāng)前頁和總頁數(shù),還有上一頁和下一頁功能。
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
一個(gè)簡單的小程序只能簡單的感受一下React,這個(gè)庫的思路和當(dāng)前流行的庫和框架相比,還是比較新穎的,值得學(xué)習(xí)~
相關(guān)文章
教你如何把Python CSV 合并到多個(gè)sheet工作表
今天我們要實(shí)現(xiàn)將多個(gè)CSV文件,合并到一個(gè)Excel文件中的,多個(gè)sheet工作表,網(wǎng)上大多方法都是將csv直接合并在一起,也不分別創(chuàng)建sheet表。接下來通過本文給大家詳細(xì)介紹下,需要的朋友參考下吧2021-11-11
python十進(jìn)制轉(zhuǎn)二進(jìn)制的詳解
在本篇文章里小編給大家整理了關(guān)于python十進(jìn)制轉(zhuǎn)二進(jìn)制的相關(guān)知識(shí)點(diǎn)內(nèi)容,需要的朋友們可以參考學(xué)習(xí)下。2020-02-02
Python3實(shí)現(xiàn)連接SQLite數(shù)據(jù)庫的方法
這篇文章主要介紹了Python3實(shí)現(xiàn)連接SQLite數(shù)據(jù)庫的方法,在Python數(shù)據(jù)庫編程中有著廣泛的應(yīng)用,需要的朋友可以參考下2014-08-08
神經(jīng)網(wǎng)絡(luò)理論基礎(chǔ)及Python實(shí)現(xiàn)詳解
這篇文章主要介紹了神經(jīng)網(wǎng)絡(luò)理論基礎(chǔ)及Python實(shí)現(xiàn)詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12
Python中的內(nèi)置函數(shù)isdigit()
這篇文章主要介紹了Python中的內(nèi)置函數(shù)isdigit(),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
pytorch和numpy默認(rèn)浮點(diǎn)類型位數(shù)詳解
這篇文章主要介紹了pytorch和numpy默認(rèn)浮點(diǎn)類型位數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02

