使用react做的聊天对话列表
刚刚接触react 可能写的地方有错误或者不完善的地方欢迎大家给指正
下面开始正题
首先分析页面基于react的特性--把页面中所有显示内容看做模块加载
- 本页面可以看做一个大的模块,我们暂且命名为commentbox
- 评论列表是由一条条的评论内容组成,所以把评论内容comment,单独作为一个模块,然后放在评论列表的模块里commentlist
- 底部的输入框作为一个输入模块commentform
页面分析完成开始准备
基于jspm工具首先安装jspm
在终端
npm init
然后安装jspm
npm install jspm --save-dev
然后配置
jspm init
安装需要的依赖
jspm install jquery
jspm install react@0.14.0-rc1
jspm install react-dom@0.14.0-rc1
本文中使用了semantic-ui的样式因此安装
jspm install semantic-ui
使用css安装
jspm install css
然后 在本地新建文件结构如下
然后在终端
browser-sync start --server --no-notify --files 'index.html,app/**/*.js'
配置本地服务器 并监视index.html和js文件的变化
下面正式开始:::::
首先我们利用react创建一个静态版本
在index.html引入js文件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>react</title> </head> <body> <div class="ui container" style="padding:30px;"> <div id="app"></div> </div> <script src="jspm_packages/system.js" charset="utf-8"></script> <script src="config.js"> </script> <script> System.import('app/main'); </script> </body> </html>
然后在main.js中
'use strict'; import 'semantic-ui/semantic.min.css!'; import React from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render( <h1 className="ui">你好</h1>, document.getElementById('app') )
就能看到页面上出现你好两个字
tips:h1标签后要有逗号分隔
因为react是模块化结构所以我们把各个模块分别写在单独的js文件中。
我们开始下最基础的commentbox组件
在组件中第一件事就是引入react
'use strict'; import React from 'react'; import $ from "jquery"; class CommentBox extends React.Component{ render(){ //render方法内写的是需要返回在页面上的元素这里有几个重要点
//1、里面的元素必须在最外层加上div等标签,否则会报错原因:初学好没弄清楚
//2、元素成对出现标签必须闭合
//3、class为保留字,所以使用className
//4、jsx语法要求组件名称首字母大写;否则报错(耽误了好长时间找不出的错~~)
return( <div className="ui comments"> <h1>评论</h1> <div className="ui divider"></div> </div> ) } } export {CommentBox as default};
然后在main.js中引入commentBox
import CommentBox from './comment/CommentBox'; //注意from后面文件路径
现在页面的显示
然后我们写评论列表commentform的js
然后把这个内容作为默认内容导出后引入到commentbox页面
然后在main页面使用commentbox标签输出,因为我们定义好组件所以我们可以直接使用组件名,来显示对应的元素
页面显示如下
然后安装相同的方法定义评论列表就不赘述了
我们如果使用react就是因为他在处理数据变化时候对于dom元素的修改效率很高
所以做了一下使用ajax读取json数据并反映到页面上
此处用到props和state等属性。
- 属性(props)是由父组件传递给子组件的;
- 状态(state)是子组件内部维护的数据,当状态发生变化的同时,组件也会进行更新。当状态发生转换时会触发不同的钩子函数,从而让开发者有机会做出相应。
首先创建一个comments.json的文件
[ {"author":"杨倩","date":"5 分钟前","text":"天气不错啊"}, {"author":"杨晨","date":"3 分钟前","text":"出去玩啊!"}, {"author":"杨倩","date":"5 分钟前","text":"天气不错啊"}, {"author":"杨晨","date":"3 分钟前","text":"出去玩啊!"}, {"author":"杨倩","date":"5 分钟前","text":"天气不错啊"}, {"author":"杨晨","date":"3 分钟前","text":"出去玩啊!"}, {"author":"王凌峰","date":"2分钟前","text":"不去"} ]
然后在main.js里面引入json
'use strict'; import 'semantic-ui/semantic.min.css!'; import React from 'react'; import ReactDOM from 'react-dom'; import CommentBox from './comment/CommentBox'; ReactDOM.render( <CommentBox url="app/comments.json" />, document.getElementById('app') )
然后commentBox.js页面通过ajax获取数据
'use strict'; import React from 'react'; import CommentList from "./CommentList"; import CommentForm from "./CommentForm"; import $ from "jquery"; class CommentBox extends React.Component{ constructor(props){ //传入props即能获取json的url super(props); this.state = {data:[]}; //给元素的state赋值一个空的数组由下边getcomments获取数据
this.getComments(); //setInterval(() => this.getComments(),5000); } handleCommentSubmit(comment){ console.log(comment ); let comments = this.state.data, newComments = comments.concat(comment); this.setState({data:newComments}); } getComments(){ $.ajax({ url: this.props.url, //取得url dataType:"json", cache:false, success: comments => { this.setState({data:comments}); //得到json数组 通过setSatate设置显示的数据对应着comment.js看 }, error:(xhr,status,error)=>{ console.log(error); } }) } render(){ return( <div className="ui comments"> <h1>评论</h1> <div className="ui divider"></div> <CommentList data={this.state.data}/> <CommentForm onCommentSubmit = {this.handleCommentSubmit.bind(this)}/> </div> ) } } export {CommentBox as default};
comment.js
'use strict'; import React from "react"; class Comment extends React.Component{ render(){ return( <div className="comment"> <div className="content"> <span className="author">{this.props.author}</span> //取得json数组中的值,props传入的为上级state的值 <div className="metadata"> <span className="date">{this.props.date}</span> </div> <div className="text">{this.props.children}</div> </div> </div> ) } } export {Comment as default};
commentform.js
'use strict'; import React from 'react'; class CommentForm extends React.Component{ handleSubmit(event){ event.preventDefault(); // console.log("提交表单……"); let author = this.refs.author.value; let text = this.refs.text.value; // console.log(text); function dataToString(d) { return[ d.getHours(), d.getMinutes(), d.getSeconds() ].join(":"); }; let date = dataToString(new Date()); this.props.onCommentSubmit({author,text,date}) } render(){ return( <form className="ui reply form" onSubmit = {this.handleSubmit.bind(this)}> <div className="field"> <input type="text" placeholder="姓名" ref="author"/> </div> <div className="field"> <textarea placeholder="评论" ref="text"></textarea> </div> <button type="submit" className="ui blue button" >添加评论 </button> </form> ) } } export {CommentForm as default};
commentlist
'use strict'; import React from 'react'; import Comment from './Comment'; class CommentList extends React.Component{ render(){ let commentNodes = this.props.data.map(comment => { return( <Comment author={comment.author} date={comment.date}> {comment.text} </Comment> ); }); return( <div> {commentNodes} </div> ) } } export {CommentList as default};