最近在寫一個項目,在寫react的過程當中遇到過不少坑,如今總結一下,爲之後的項目做參考.另外借此項目來比較一下 vue.js 和 react.js 之間的一些異同.html
剛剛開始寫組件的時候,感受難度不大(跟vue差很少)。最有意思的應該是jsx語法,我的感受,jsx的功能性確實比vue的template更強,並且可讀性更高.vue
舉個栗子
// vue <p :id="text" :class="{'active':isActive}" v-text="'hello! ' + msg"></p>
// jsx <p id={text} className={isActive && 'active'}>hello !{msg}</p>
{}
表明要執行的js語句,它的效果相似 return
,它會有返回值.這樣的話,更好理解jsx的內容,jsx裏面的dom不是真正的dom,只是一種表示dom的語法,{}
裏面的內容能夠徹底理解爲js,這種整個jsx就能夠完成理解爲原生js寫的html模版.:
,在jsx裏面則不須要.contentText
不使用{{}}
來渲染,使用由於在vue頁面生成以前,模版語法部分沒有渲染出來,就會在頁面上先出現{{content}}
,再一閃變成真正的文本內容.再舉個數組遍歷渲染的栗子
// vue <ul> <li v-for="(item,index) in list" :key="index" v-if="showItem(item)"> <span v-text="item.label"></span> </li> </ul> // vue的methods屬性 methods:{ showItem(item){ return item.label.indexOf('abc') !== -1 } }
// jsx <ul> {list.map((item,index) => { return item.label.indexOf('abc') !== -1 && ( <li key={index}> <span>{item.label}</span> </li> ) })} </ul>
你會發現,在一些比較簡單渲染需求時,使用vue的template會比較簡單直接,並且很易懂.可是若是涉及一些比較複雜的邏輯處理渲染,jsx更直觀,由於jsx的語法跟js的差別不大,至關於用js來描述須要如何渲染dom結構.固然jsx並非說能夠完成使用js的語法來寫dom,{}
裏面只能是一個表達式,因此像if else
或者switch
這種語法在{}
是不能用的.react
在寫redux的時候,不是很習慣。後來慢慢的去適應。因爲還用到了saga
,以致於書寫方法上與redux官方的推薦的有所不一樣。vuex
'action type'定義的不一樣類型。
第一種狀況:觸發action
以後直接commit一個reducer
。redux
// action {type:'do/update-some-data',payload}
第二種狀況,觸發的action
會被saga
攔截,而後saga
完成必定的操做後(通常是從後臺獲取數據);put
一個action
,做用到reducer
。數組
// saga action {type:'start/get-some-data',payload} // reducer action {type:'success/get-some-data',payload} {type:'failed/get-some-data',payload} {type:'error/get-some-data',payload}
由於之前在寫代碼的時候一直都沒有肯定好一個規範,致使代碼風格一直有變化(已經被同事吐槽好幾回了)。後來在這個項目裏面看了其餘的同事的代碼再結合網上推薦的一些代碼規範,目前總結出一些當心得(也不算什麼心得)。dom
1.註釋的問題我我的一直都重視的,一份好的註釋可讓別人在開始看代碼以前就能對內容有一個大概清晰的瞭解。
/** * @name:組件名稱 * @author:誰維護的 * @version:2017-12-28 日期或者版本號 * @description:描述 * 你會發現沒有’param‘,這個部分在組件定義的地方會提到。 */
這些只是基本的信息,還能夠添加其餘你想加的內容。函數
2.模塊引入的部分通常有這些分類
3.內部方法
內部方法通常是針對該組件須要的功能而定義的,並且不想跟類一塊兒export出去。好比,組件裏拿到後臺的一個對象數組,須要根據這個數組的信息計算出一個值,而後在組件中使用。
若是這個方法在多個組件中使用到的話,還能夠把它提到utils
文件夾中。this
4.組件定義
通常狀況下,組件都會使用類來定義。好比:
class MyComponent extends Component{ static defaultProps = { a:0, b:1 } constructor(props) { super(props) this.state = { c:2, d:3 } } handleClick = () = >{ // some stuff } render() { const {a,b} = this.props const {c,d} = this.state const e = false return( <div> <div a={a} b={b}></div> <div {...{a,c}}></div> <div {...this.props} {...this.state}></div> e && {<div>some code</div>} </div> ) } }
首先,爲啥子要寫defaultProps
?我以爲,有兩點:spa
state
就略過了。
類的方法。這裏使用了箭頭函數
來定義,主要是爲了使用this
,由於大多數狀況下,handle裏面都會調用this.setState
,這樣寫就不須要去constructor
一個個bind(this)
了。其實若是方法裏面沒有使用指向類的this
,用函數定義的方式也是能夠的。
render部分。我通常習慣將使用到的props
和state
以及其餘的數據所有在return
前定義出來。這樣會更清晰明白組件裏面使用了哪些數據。
另外是給元素設置屬性的一些小技巧。平時最經常使用的方式是這樣的key={value}
,還可使用對象解構的方式設置屬性。
redux seletct & export
說到redux
必定要扯上vuex
(看完下面的內容,若是有不一樣意見的戰友,請不要打我)。
這裏先從組件部分來看一下redux
和vuex
的區別。在組件裏面主要是看如何讓當前組件使用到store
中的數據和方法。
// react import React, { Component } from 'react' import { connect } from 'react-redux' import * as actions from '../actions' import { bindActionCreators } from 'redux' class MyComponent extends Component{} function mapStateToProps(state){ return { ...state, stateOne:state=>state.stateOne, stateTwo:state=>state.stateTwo } } functino mapDispatchToProps(dispatch){ return { ...bindActionCreators(actions,dispatch), handleOne:(arg)=>dispatch(actions.handleOne(arg)), handleTwo:(arg)=>dispatch(actions.handleTwo(arg)) } } export connect(mapStateToProps,mapDispatchToProps)(MyComponent)
react裏面要使用connect
方法把state和dispatcher和當前組件鏈接起來.
// vue import { createNamespacedHelpers } from 'vuex' const { mapState, mapActions } = createNamespacedHelpers('theModule') export default { computed:{ ...mapState(['stateOne','stateTwo']), ...mapState({ stateThree:state=>state.theModule.stateThree, stateFour:state=>state.theModule.stateFour }) }, methods:{ ...mapActions(['handleOne','handleTwo']), ...mapActions({ handleThree:'actionThree', handleFour:'actionFour' }) } }
在vue裏面也有相應的輔助函數,並且vuex的store
包含來數據和方法,在根組件注入以後,全部的子組件均可以經過this.$store
使用,輔助函數只是用來過濾而已.
待續...