webpack+es6+node+react初实践及总结

以前对于react的认识只存在与据说,说他有啥virtual DOM,很好的组件化,效率很高之类的,,不过一直没有学习,昨天闲着无聊就开始学习react.发现jsx的写法真是666啊,因为是刚开始学习,因此总的经验不是不少。
我跟着其官网上的教程作了一个评论框的功能,后台用的是node,并无连接数据库,只是文件流的读写;
最终结果:
clipboard.pngjavascript

文件结构:

  • react_commentcss

    • node_modulesjava

    • publicnode

      • buildreact

        • build.jswebpack

        • build.js.mapgit

      • jses6

        • comment.jsgithub

        • comment_box.jsweb

        • 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-201五、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'));
  1. 这里必定要注意的是渲染组件用的是react-dom,而不是react,因此要把它也require进来

  2. 必定要用原生的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};
  1. 因为在es6中使用类的构造函数constructor来代替了getInitialState,因此之前在getInitialState里声明的初始量要变化到在constructor

  2. 另外就是在组件上绑定的函数的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规范以上只是一个初学者的的见解,若是有不足或者错误的地方,欢迎指出

相关文章
相关标签/搜索