之前对于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, status, 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});
},
error(xhr, status, err) {
_this.setState({data: comments});
console.error(_this.props.url, status, 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规范
以上只是一个初学者的的看法,如果有不足或者错误的地方,欢迎指出
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。