用ReactJS和Python的Flask框架编写留言板的代码示例

473次阅读  |  发布于5年以前

近期要在生产环境上使用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,这个库的思路和当前流行的库和框架相比,还是比较新颖的,值得学习~

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8