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

前端之家收集整理的这篇文章主要介绍了webpack+es6+node+react初实践及总结前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

文件结构:

  • react_comment@H_301_16@

    • node_modules@H_301_16@

    • public@H_301_16@

      • build@H_301_16@

        • build.js@H_301_16@

        • build.js.map@H_301_16@

      • js@H_301_16@

        • comment.js@H_301_16@

        • comment_Box.js@H_301_16@

        • commemt_form.js@H_301_16@

        • comment_list.js@H_301_16@

        • entry.js@H_301_16@

      • scss@H_301_16@

        • comment.scss@H_301_16@

    • server@H_301_16@

      • server.js@H_301_16@

    • comment.json@H_301_16@

    • package.json@H_301_16@

    • webpack.config.js@H_301_16@

webpack.config.js:

  1. var path = require('path'),webpack = require('webpack');
  2. var commonLoaders = [
  3. {test:/\.js$/,loader:'babel',exclude:'/node_modules/'},//exclude:不包含这个文件夹下的目录,不然babel也会编译里面的js文件,导致速度变慢
  4. {test:/\.scss$/,loader:'style!css!autoprefixer!sass'}
  5. ];
  6. var path = path.resolve(__dirname,'public/build');
  7. module.exports = {
  8. entry:[
  9. './public/js/entry.js' //指定入口文件
  10. ],output:{ //指定输出文件路径及name
  11. path:path,filename:'build.js'
  12. },module:{
  13. loaders:commonLoaders
  14. },resolve:{
  15. extensions:['','.js','.scss']
  16. },babel:{ //这里我是使用的是babel-loader、babel-preset-2015、babel-preset-react,并没有使用jsx-loader,所以这里作如下配置:
  17. presets:['es2015','react']
  18. }
  19. };

数据源:

  1. [
  2. {
  3. "id": 1388534400000,"author": "Pete Hunt","text": "Hey there!"
  4. }
  5. ]

入口文件

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {CommentBox} from './comment_Box';
  4. import reset from '../scss/comment';
  5. ReactDOM.render(<CommentBox url='/api/comments' pollInterval={2000} />,document.getElementById('content'));
  1. 这里一定要注意的是渲染组件用的是react-dom,而不是react,所以要把它也require进来@H_301_16@

  2. 一定要用原生的document.getElementById()获取容器@H_301_16@

最外层组件

  1. import React from 'react';
  2. import $ from 'webpack-zepto';
  3. import {CommentList} from './comment_list';
  4. import {CommentForm} from './comment_form';
  5. class CommentBox extends React.Component{
  6. constructor(props){
  7. super(props)
  8. this.state = {data: []};
  9. this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
  10. }
  11. loadCommentsFromServer(){
  12. let _this = this;
  13. $.ajax({
  14. url:_this.props.url,dataType:'json',cache:false,success(data){
  15. _this.setState({data:data});
  16. },error(xhr,status,err){
  17. console.error(_this.props.url,err.toString());
  18. }
  19. })
  20. }
  21. componentDidMount(){
  22. this.loadCommentsFromServer();
  23. // setInterval(this.loadCommentsFromServer.bind(this),this.props.pollInterval);
  24. }
  25. handleCommentSubmit(comment){
  26. let comments = this.state.data;
  27. comment.id = Date.now();
  28. let newComments = [...comments,...comment];
  29. this.setState({
  30. data:newComments
  31. });
  32. let _this = this;
  33. $.ajax({
  34. url: _this.props.url,dataType: 'json',type: 'POST',data: comment,success(data) {
  35. _this.setState({data: data});
  36. },err) {
  37. _this.setState({data: comments});
  38. console.error(_this.props.url,err.toString());
  39. }
  40. })
  41. }
  42. render(){
  43. return(
  44. <div className="commentBox">
  45. <h1>Comments:</h1>
  46. <CommentList data={this.state.data} />
  47. <CommentForm onCommentSubmit={this.handleCommentSubmit} />
  48. </div>
  49. );
  50. }
  51. }
  52. export {CommentBox};
  1. 由于在es6中使用类的构造函数constructor来代替了getInitialState,所以以前在getInitialState里声明的初始量要变化到在constructor中@H_301_16@

  2. 另外就是在组件上绑定的函数this指向问题坑了我好久@H_301_16@

  1. import React from 'react';
  2. class CommentForm extends React.Component{
  3. constructor(props){
  4. super(props);
  5. this.state = {author:'',text:''};
  6. }
  7. handleAuthorChange(e){
  8. this.setState({
  9. author:e.target.value
  10. })
  11. }
  12. handleTextChange(e){
  13. this.setState({
  14. text:e.target.value
  15. })
  16. }
  17. handleSubmit(e){
  18. e.preventDefault();
  19. let author = this.state.author.trim(),text = this.state.text.trim();
  20. if(!text || !author){
  21. alert('请填写完整');
  22. return false;
  23. }
  24. this.props.onCommentSubmit({
  25. author:author,text:text
  26. });
  27. this.setState({
  28. author:'',text:''
  29. })
  30. }
  31. render(){
  32. return(
  33. <form className='commentForm' onSubmit={this.handleSubmit.bind(this)}>
  34. <input type='text' placeholder='name' value={this.state.author}
  35. onChange={e => this.handleAuthorChange(e)} />
  36. <input type='text' placeholder='say something...' value={this.state.text}
  37. onChange={this.handleTextChange.bind(this)} />
  38. <input type='submit' value='Post' />
  39. </form>
  40. );
  41. }
  42. }
  43. export {CommentForm};

在这个组件中,我给两个input绑定了函数,一开始以为函数里的this指向的是组件本身,后来才发现是window,原因是onChange的回调是在浏览器全局对象执行的,此时的this并不指向定义的React组件部分,如果不用es6,它是默认绑定到组件上的,所以这里要修改this的指向:@H_301_16@

  1. 1. onChange={e => this.handleAuthorChange(e)}
  2. 2. onChange={this.handleAuthorChange.bind(this)}
  3. 3. constructor(props){ //在构造器里面绑定,推荐
  4. super(props)
  5. this.state = {data: []};
  6. this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
  7. }

具体的代码我已放到github上,有需要的可以参考:github
此外,有一篇关于react规范的文章有兴趣的也可以看看:react规范以上只是一个初学者的的看法,如果有不足或者错误的地方,欢迎指出@H_301_16@

猜你在找的React相关文章