react 項目總結

前言

最近在寫一個項目,在寫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>
  1. 在jsx裏面沒有指令,並且jsx裏面 {} 表明要執行的js語句,它的效果相似 return ,它會有返回值.這樣的話,更好理解jsx的內容,jsx裏面的dom不是真正的dom,只是一種表示dom的語法,{}裏面的內容能夠徹底理解爲js,這種整個jsx就能夠完成理解爲原生js寫的html模版.
  2. 屬性計算的部分,vue裏面須要在屬性名前面加:,在jsx裏面則不須要.
  3. 另外,在vue裏面的dom的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

在寫redux的時候,不是很習慣。後來慢慢的去適應。因爲還用到了saga,以致於書寫方法上與redux官方的推薦的有所不一樣。vuex

'action type'定義的不一樣類型。
  1. action ===> reducer
  2. action ===> saga ===> reducer

第一種狀況:觸發action以後直接commit一個reducerredux

// 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.仍是從組件開始

  1. 組件註釋
  2. 模塊引入
  3. 內部方法
  4. 組件類定義
  5. redux select
  6. export
1.註釋的問題我我的一直都重視的,一份好的註釋可讓別人在開始看代碼以前就能對內容有一個大概清晰的瞭解。
/**
 * @name:組件名稱
 * @author:誰維護的
 * @version:2017-12-28 日期或者版本號
 * @description:描述
 * 你會發現沒有’param‘,這個部分在組件定義的地方會提到。
 */

這些只是基本的信息,還能夠添加其餘你想加的內容。函數

2.模塊引入的部分通常有這些分類
  1. 依賴。例如庫或者插件
  2. 子組件
  3. 資源文件。例如默認的圖標或者背景圖什麼的。
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

  1. 知道在使用這個組件的時候,應該傳入哪些參數,都有什麼意義。這樣比在組件頭註釋寫更具體。
  2. 設置默認值,避免使用時沒有傳參,致使一些bug。

state就略過了。

類的方法。這裏使用了箭頭函數來定義,主要是爲了使用this,由於大多數狀況下,handle裏面都會調用this.setState,這樣寫就不須要去constructor一個個bind(this)了。其實若是方法裏面沒有使用指向類的this,用函數定義的方式也是能夠的。

render部分。我通常習慣將使用到的propsstate以及其餘的數據所有在return前定義出來。這樣會更清晰明白組件裏面使用了哪些數據。
另外是給元素設置屬性的一些小技巧。平時最經常使用的方式是這樣的key={value},還可使用對象解構的方式設置屬性。

redux seletct & export

說到redux必定要扯上vuex(看完下面的內容,若是有不一樣意見的戰友,請不要打我)。
這裏先從組件部分來看一下reduxvuex的區別。在組件裏面主要是看如何讓當前組件使用到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使用,輔助函數只是用來過濾而已.

待續...

相關文章
相關標籤/搜索