近期要在生产环境上使用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,这个库的思路和当前流行的库和框架相比,还是比较新颖的,值得学习~
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]