以前對於react
的認識只存在與據說,說他有啥virtual DOM
,很好的組件化,效率很高之類的,,不過一直沒有學習,昨天閒着無聊就開始學習react
.發現jsx
的寫法真是666啊,因爲是剛開始學習,因此總的經驗不是不少。
我跟着其官網上的教程作了一個評論框的功能,後臺用的是node
,並無連接數據庫,只是文件流的讀寫;
最終結果:
javascript
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
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'));
這裏必定要注意的是渲染組件用的是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規範以上只是一個初學者的的見解,若是有不足或者錯誤的地方,歡迎指出