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規範以上只是一個初學者的的見解,若是有不足或者錯誤的地方,歡迎指出

相關文章
相關標籤/搜索