之前对于react
的认识只存在与听说,说他有啥virtual DOM
,很好的组件化,效率很高之类的,,不过一直没有学习,昨天闲着无聊就开始学习react
.发现jsx
的写法真是666啊,由于是刚开始学习,所以总的经验不是很多。
我跟着其官网上的教程做了一个评论框的功能,后台用的是node
,并没有链接数据库,只是文件流的读写;
最终结果:
文件结构:
-
react_comment
node_modules
-
public
-
build
build.js
build.js.map
-
js
comment.js
comment_Box.js
commemt_form.js
comment_list.js
entry.js
-
scss
comment.scss
-
-
server
server.js
comment.json
package.json
webpack.config.js
webpack.config.js:
var path = require('path'),webpack = require('webpack'); var commonLoaders = [ {test:/\.js$/,loader:'babel',exclude:'/node_modules/'},//exclude:不包含这个文件夹下的目录,不然babel也会编译里面的js文件,导致速度变慢 {test:/\.scss$/,loader:'style!css!autoprefixer!sass'} ]; var path = path.resolve(__dirname,'public/build'); module.exports = { entry:[ './public/js/entry.js' //指定入口文件 ],output:{ //指定输出文件路径及name path:path,filename:'build.js' },module:{ loaders:commonLoaders },resolve:{ extensions:['','.js','.scss'] },babel:{ //这里我是使用的是babel-loader、babel-preset-2015、babel-preset-react,并没有使用jsx-loader,所以这里作如下配置: presets:['es2015','react'] } };
数据源:
[ { "id": 1388534400000,"author": "Pete Hunt","text": "Hey there!" } ]
入口文件:
import React from 'react'; import ReactDOM from 'react-dom'; import {CommentBox} from './comment_Box'; import reset from '../scss/comment'; ReactDOM.render(<CommentBox url='/api/comments' pollInterval={2000} />,document.getElementById('content'));
这里一定要注意的是渲染组件用的是
react-dom
,而不是react
,所以要把它也require进来一定要用原生的
document.getElementById()
来获取容器
最外层组件
import React from 'react'; import $ from 'webpack-zepto'; import {CommentList} from './comment_list'; import {CommentForm} from './comment_form'; class CommentBox extends React.Component{ constructor(props){ super(props) this.state = {data: []}; this.handleCommentSubmit = this.handleCommentSubmit.bind(this); } loadCommentsFromServer(){ let _this = this; $.ajax({ url:_this.props.url,dataType:'json',cache:false,success(data){ _this.setState({data:data}); },error(xhr,status,err){ console.error(_this.props.url,err.toString()); } }) } componentDidMount(){ this.loadCommentsFromServer(); // setInterval(this.loadCommentsFromServer.bind(this),this.props.pollInterval); } handleCommentSubmit(comment){ let comments = this.state.data; comment.id = Date.now(); let newComments = [...comments,...comment]; this.setState({ data:newComments }); let _this = this; $.ajax({ url: _this.props.url,dataType: 'json',type: 'POST',data: comment,success(data) { _this.setState({data: data}); },err) { _this.setState({data: comments}); console.error(_this.props.url,err.toString()); } }) } render(){ return( <div className="commentBox"> <h1>Comments:</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); } } export {CommentBox};
由于在
es6
中使用类的构造函数constructor
来代替了getInitialState
,所以以前在getInitialState
里声明的初始量要变化到在constructor
中另外就是在组件上绑定的函数的
this
指向问题坑了我好久
import React from 'react'; class CommentForm extends React.Component{ constructor(props){ super(props); this.state = {author:'',text:''}; } handleAuthorChange(e){ this.setState({ author:e.target.value }) } handleTextChange(e){ this.setState({ text:e.target.value }) } handleSubmit(e){ e.preventDefault(); let author = this.state.author.trim(),text = this.state.text.trim(); if(!text || !author){ alert('请填写完整'); return false; } this.props.onCommentSubmit({ author:author,text:text }); this.setState({ author:'',text:'' }) } render(){ return( <form className='commentForm' onSubmit={this.handleSubmit.bind(this)}> <input type='text' placeholder='name' value={this.state.author} onChange={e => this.handleAuthorChange(e)} /> <input type='text' placeholder='say something...' value={this.state.text} onChange={this.handleTextChange.bind(this)} /> <input type='submit' value='Post' /> </form> ); } } export {CommentForm};
在这个组件中,我给两个input绑定了函数,一开始以为函数里的this指向的是组件本身,后来才发现是window
,原因是onChange的回调是在浏览器全局对象执行的,此时的this并不指向定义的React组件部分,如果不用es6,它是默认绑定到组件上的,所以这里要修改this的指向:
1. onChange={e => this.handleAuthorChange(e)} 2. onChange={this.handleAuthorChange.bind(this)} 3. constructor(props){ //在构造器里面绑定,推荐 super(props) this.state = {data: []}; this.handleCommentSubmit = this.handleCommentSubmit.bind(this); }
具体的代码我已放到github上,有需要的可以参考:github
此外,有一篇关于react规范的文章有兴趣的也可以看看:react规范以上只是一个初学者的的看法,如果有不足或者错误的地方,欢迎指出