近期要在生產環境上使用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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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;<br> |
MessageList
留言的列表展示,在寫列表之前,把每條留言寫成一個組件
Message.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
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,這個庫的思路和當前流行的庫和框架相比,還是比較新穎的,值得學習~