之前对于react
的认识只存在与听说,说他有啥virtual DOM
,很好的组件化,效率很高之类的,,不过一直没有学习,昨天闲着无聊就开始学习react
.发现jsx
的写法真是666啊,由于是刚开始学习,所以总的经验不是很多。
我跟着其官网上的教程做了一个评论框的功能,后台用的是node
,并没有链接数据库,只是文件流的读写;
最终结果:
@H_301_16@
文件结构:
-
react_comment@H_301_16@
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!"
- }
- ]
入口文件:
这里一定要注意的是渲染组件用的是
react-dom
,而不是react
,所以要把它也require进来@H_301_16@
最外层组件
- 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
中@H_301_16@
- 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的指向:@H_301_16@
- 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规范以上只是一个初学者的的看法,如果有不足或者错误的地方,欢迎指出@H_301_16@