zoukankan      html  css  js  c++  java
  • React学习笔记1——评论框的实现

    学习链接:http://reactjs.cn/react/docs/tutorial-zh-CN.html

    实现功能:主要分两个部分:1、评论列表的展示 2、评论框的输入提交

    一、组件

    1、拆分组件

    一个大容器CommentBox中包含CommetList和CommetForm,CommetList中又包含多个Commet组件

    2、CommentBox组件

    var CommentBox = React.createClass({
        render: function(){
        return(
          <div>
            <CommentList />
            <CommentForm />
          </div>
        )
      }
    })
    ReactDOM.render({
      <CommetBox />,
      document.getElementById('content')
    })
    //首先在CommentBox中添加两个组件,然后将CommetBox渲染到页面上
    1. React组件必须用大写字母开头,且标签必须闭合,通过return函数返回的标签也必须是闭合的。比如我将<CommentList/>和<CommentForm/>外面的div去掉,就会报错
    2. React.createClass 是ES5形式的定义组件;后面又有了React.Component ,ES6形式的定义组件。(React定义组件的方法http://www.cnblogs.com/wonyun/p/5930333.html)
    3. ReactDOM.render({element, container, callback})渲染组件的方法,接收三个参数element 要渲染的组件,container渲染的组件要插入在DOM中的位置,callback回调函数,可选参数,传入时会在组件渲染完成后调用
    4. render React生命周期中的初始化阶段的一个函数,用来组装组件的html结构,必须要有返回值,返回的也可以是null 或者false

    3、CommentList组件

    var CommetList= React.createClass({
        render: function(){
        return(
          <div>    //包含多个comment组件
            <Comment />
            <Comment />
          </div>
        )
      }
    })
    

    4、Comment组件

    var Comment = React.createClass({
        render: function(){
        return(
          <div>    
            <h3>"this is author"</h3>    //展示作者
            <div>"this is comment text"</div>    //展示评论       </div>     )   } })

    5、CommentForm组件

    var CommentForm = React.createClass({
        render: function(){
        return(
          <form>         <input type='text' placeholder='enter your name'/>
            <input type='text' placeholder='say something ...'/>
            <input type='submit' value='submit'/>
          </form>
               )   } })

    二、数据

    1、简介

    React父子组件数据的传递可使用props和state。props属性是组件与生俱来的不可以由组件自己修改,state状态是事物自己的,可不断变化。主要区分是组件在运行时需要修改的是state,此外所有的数据都可以是props

      属性 状态
    是否能从父组件获取初始值 T F
    是否由父组件修改 T F
    能否在组件内部设置默认值 T T
    能否在组件内部修改 F T
    能否设置子组件的初始值 T F
    能否修改子组件的值 T F

    (1)、this.props  用来访问从父组件传进来的数据

    (2)、this.state  用来访问动态更新的数据

    (3)、this.setState()  将服务器获取的数据更新到状态中(更新CommetList中的数据)

    (4)、父子组件之间的数据通信,父组件通过this.props将数据传递给子组件;子组件通过委托(delegate)即事件处理函数与父组件通信,子组件触发函数,父组件处理。

    2、获取、更新数据

    ReactDOM.render( 
      <CommetBox url='/api/comments', pollInterval={2000}>,  //这个请求地址是在server中设置好了,
      document.getElementById('content')
    )
    var CommentBox = React.createClass({
      loadCommentsFromServer: function(){    
        $.ajax({
          url: this.props.url,     //通过this.props获取父组件中的属性
          dataType: 'json',
          cache: false,
          success: function(data){
            this.setState({data:data})        //动态更新的关键是通过this.setState()设置状态
          }.bind(this),
          error: function(xhr, status, err) {
            console.error(this.props.url, status, err.toString());
          }.bind(this)
     
       })
      },
      getInitialState:function(){
        return {data:[]}  
      },
      
      componentDidMount: function(){  
        this.loadCommentsFromServer();                      //这里通过设置定时器实时刷新数据,为了避免刚开始数据要在间隔时间后才出来的情况,所以先调用一次获取数据
        setInterval(this.loadCommentsFromServer, this.props.pollInterval);
      },
      render: function(){
        return(
          <div>
            <CommentList data={this.state.data} />
            <CommentForm />
          </div>
        )
      }
    })
    var CommentList = React.creatClass({
      render: function(){
        var commnetNodes = this.props.data.map(function(comment){  //data的数据结构[ {"author": "Pete Hunt", "text": "This is one comment"}, {"author": "Jordan Walke", "text": "This is *another* comment"} ]
          return(
            <Comment key={comment.id} author={comment.author}>
              {commnet.text}
            </Comment>
          )
        })
        return(
          <div>
            {commentNodes}
          </div>
        )
      }
    })
    var Comment = React.createClass({
      return(
        <div>
          <h3>
            {this.props.author}
          </h3>
          <p>
            {this.children.text.toString()}
          </p>
        </div>
      )
    })

    涉及到的生命周期:

    (1)getInitialState 生命周期初始化阶段,初始化每个实例特有的状态,在生命周期里只执行一次,必须返回一个对象或者null

    (2)componentDidMount 生命周期初始化阶段,在成功render并渲染完真实的DOM后react自动调用的方法,此时可以修改DOM。如果要在渲染后对DOM操作就是在这个阶段里。

    三、事件

    子组件通过事件与父组件通信,子组件触发,父组件处理。

    1、添加评论,绑定事件

    基本的操作在子组件CommentForm中完成

    var CommentForm = React.createClass({
      getInitialState:function(){
        return({author:'',text:''})
      },
      handleAuthorChange: function(e){
        this.setState({author: e.target.value})    //通过this.setState()保证输入实时更新状态
      },
      handleTextChange: function(e){
        this.setState({text: e.target.value})
      },
      handleSubmit: function(e){            //提交事件,清空表单
        e.preventDefault();              //阻止提交表单的默认行为
        var author = this.state.author.trim();
        var text = this.state.text.trim();
        if (!author || !text) {
          return
        }
        this.setState({author:'',text:''})
      },
      
      render:function(){
        return(
          <form onSubmit={this.handleSubmit}>      //提交表单
          <input
            type='text'
            value={this.state.author}
            placeholder='your name'
            onChange = {this.handleAuthorChange}    //绑定事件
          />
          <input
            type='text'
            value={this.state.text}
            placeholder='enter something'
            onChange = {this.handleTextChange}         //绑定事件
          />
          <input type='submit' value='提交' />    
          </form>
          )
      }
    })

    2、提交更新评论  子组件传递数据给父组件

    提交评论时需要刷新评论列表来包含这条评论。发送请求及刷新评论的操作在CommentBox(即父组件)中完成,原因是:CommentBox中有评论列表的状态。现在需要把CommentForm(子组件)中的数据传递到CommentBox(父组件)中,子组件通过事件与父组件通信。所以在父组件中传递一个回调函数(handleCommetSubmit)到子组件中,子组件绑定这个函数传值即可,这样只要子组件CommentForm中的事件被触发,父组件CommentBox中的回调函数handCommentSubmit就会被调用。

    //CommentBox中
    handleCommentSubmit: function(comment){ $.ajax({ url:this.props.url, dataType:'json', type:'POST', data: comment, success: function(data){ this.setState({data:data}) }.bind(this), error: function(xhr, status, err){ this.setState({data: comments}); console.log(this.props.url, status, err.toString()) }.bind(this) })
    render: function(){
        return(
          <div>
            <CommentList data={this.state.data}/>
            <CommentForm onCommentSubmit={this.handleCommentSubmit}/> //传递回调函数给子组件
          </div>
          )
      }

    //CommentForm中
      handleSubmit: function(e){
        e.preventDefault();
        var author = this.state.author.trim();
        var text = this.state.text.trim();
        if (!author || !text) {
          return
        }
        this.props.onCommentSubmit({author:author,text:text})    //绑定回调函数,则handleSubmit事件一触发,回调函数就会被调用
        this.setState({author:'',text:''})
      },

    四、优化

     1、更新太慢要等请求完成后页面才会展示新的评论,手动添加新评论到列表中让体验更快一些

      handleCommentSubmit: function(comment) {
        var comments = this.state.data;
        comment.id = Date.now();
        var newComments = comments.concat([comment]);this.setState({data: newComments});
        $.ajax({
          url: this.props.url,
          dataType: 'json',
          type: 'POST',
          data: comment,
          success: function(data) {
            this.setState({data: data});
          }.bind(this),
          error: function(xhr, status, err) {
            this.setState({data: comments});
            console.error(this.props.url, status, err.toString());
          }.bind(this)
        });
      }

    2、插入的文本中如果有HTML标签,我们是默认展示成输入的样子的,如点<a href='.....'>这里</a>可以跳转哦。如果我们想要把这种样子的评论真正的渲染成HTML,可以用到dangerouslySetInnerHTML

    <span dangerouslySetInnerHTML={{ __html: this.props.children.toString()}}/>
  • 相关阅读:
    FZU.Software Engineering1816 ·The Second Assignment of the Team
    18软工实践-第五次作业-结对作业2
    福大软工1816 · 第四次作业
    软件工程实践第三次作业——结对作业(一)
    软工第二次作业——个人项目
    福大软工1816 · 团队现场编程实战(抽奖系统)
    Alpha 冲刺 (3/10)
    Alpha 冲刺 (2/10)
    Alpha 冲刺 (1/10)
    福大软工 · 第七次作业
  • 原文地址:https://www.cnblogs.com/xxchi/p/6678021.html
Copyright © 2011-2022 走看看