taro 最佳實踐


對 JSX 支持程度補充說明:

  1. 不能在包含 JSX 元素的 map 循環中使用 if 表達式
  2. 不能使用 Array#map 之外的方法操作 JSX 數組
  3. 不能在 JSX 參數中使用匿名函數
  4. 暫不支持在 render() 之外的方法定義 JSX
  5. 不允許在 JSX 參數(props)中傳入 JSX 元素
  6. 不能在 JSX 參數中使用對象展開符
  7. 不支持無狀態組件

最佳編碼方式

  • 組件樣式說明
    微信小程序的自定義組件樣式默認是不能受外部樣式影響的,例如在頁面中引用了一個自定義組件,在頁面樣式中直接寫自定義組件元素的樣式是無法生效的。這一點,在 Taro 中也是一樣,而這也是與大家認知的傳統 web 開發不太一樣。
  • 給組件設置 defaultProps
    在微信小程序端的自定義組件中,只有在 properties 中指定的屬性,才能從父組件傳入並接收。
    而在 Taro 中,對於在組件代碼中使用到的來自 props 的屬性,會在編譯時被識別並加入到編譯后的 properties 中。
    能會有某一屬性沒有使用而是直接傳遞給子組件的情況,這種情況是編譯時無論如何也處理不到的,這時候就需要大家在編碼時給組件設置 defaultProps 來解決了。
    組件設置的 defaultProps 會在運行時用來彌補編譯時處理不到的情況,里面所有的屬性都會被設置到 properties 中初始化組件,正確設置 defaultProps 可以避免很多異常的情況的出現。
  • 組件傳遞函數屬性名以 on 開頭
    這是因為,微信小程序端組件化是不能直接傳遞函數類型給子組件的,在 Taro 中是借助組件的事件機制來實現這一特性,而小程序中傳入事件的時候屬性名寫法為 bindmyevent 或者 bind:myevent
<!-- 當自定義組件觸發“myevent”事件時,調用“onMyEvent”方法 -->
<component-tag-name bindmyevent="onMyEvent" />
<!-- 或者可以寫成 -->
<component-tag-name bind:myevent="onMyEvent" />

所以 Taro 中約定組件傳遞函數屬性名以 on 開頭,同時這也和內置組件的事件綁定寫法保持一致了。

  • 小程序端不要在組件中打印傳入的函數
    前面已經提到小程序端的組件傳入函數的原理,所以在小程序端不要在組件中打印傳入的函數,因為拿不到結果,但是 this.props.onXxx && this.props.onXxx() 這種判斷函數是否傳入來進行調用的寫法是完全支持的。
  • 小程序端不要將在模板中用到的數據設置為 undefined,用 null 替代
    由於小程序不支持將 data 中任何一項的 value 設為 undefined ,在 setState 的時候也請避免這么用。你可以使用 null 來替代。
  • 小程序端不要在組件中打印 this.props.children
    在微信小程序端是通過 來實現往自定義組件中傳入元素的,而 Taro 利用 this.props.children 在編譯時實現了這一功能, this.props.children 會直接被編譯成 標簽,所以它在小程序端屬於語法糖的存在,請不要在組件中打印它。
  • 組件屬性傳遞注意
    不要以 id、class、style 作為自定義組件的屬性與內部 state 的名稱,因為這些屬性名在微信小程序中會丟失。
  • 組件 state 與 props 里字段重名的問題
    不要在 state 與 props 上用同名的字段,因為這些字段在微信小程序中都會被掛在 data 上。
  • 小程序中頁面生命周期 componentWillMount 不一致問題
    由於微信小程序里頁面在 onLoad 時才能拿到頁面的路由參數,而頁面 onLoad 前組件都已經 attached 了。因此頁面的 componentWillMount 可能會與預期不太一致。例如:
// 錯誤寫法
render () {
  // 在 willMount 之前無法拿到路由參數
  const abc = this.$router.params.abc
  return <Custom adc={abc} />
}

// 正確寫法
componentWillMount () {
  const abc = this.$router.params.abc
  this.setState({
    abc
  })
}
render () {
  // 增加一個兼容判斷
  return this.state.abc && <Custom adc={abc} />
}

對於不需要等到頁面 willMount 之后取路由參數的頁面則沒有任何影響。

  • 組件的 constructor 與 render 提前調用
    很多細心的開發者應該已經注意到了,在 Taro 編譯到小程序端后,組件的 constructor 與 render 默認會多調用一次,表現得與 React 不太一致。
    這是因為,Taro 的組件編譯后就是小程序的自定義組件,而小程序的自定義組件的初始化時是可以指定 data 來讓組件擁有初始化數據的。開發者一般會在組件的 constructor 中設置一些初始化的 state,同時也可能會在 render 中處理 state 與 props 產生新的數據,在 Taro 中多出的這一次提前調用,就是為了收集組件的初始化數據,給自定義組件提前生成 data ,以保證組件初始化時能帶有數據,讓組件初次渲染正常。
    所以,在編碼時,需要在處理數據的時候做一些容錯處理,這樣可以避免在 constructor 與 render 提前調用時出現由於沒有數據導致出錯的情況。
  • JS 編碼必須用單引號
    在 Taro 中,JS 代碼里必須書寫單引號,特別是 JSX 中,如果出現雙引號,可能會導致編譯錯誤。
  • 環境變量 process.env 的使用
    不要以解構的方式來獲取通過 env 配置的 process.env 環境變量,請直接以完整書寫的方式 process.env.NODE_ENV 來進行使用
  • 預加載
    在微信小程序中,從調用 Taro.navigateTo、Taro.redirectTo 或 Taro.switchTab 后,到頁面觸發 componentWillMount 會有一定延時。因此一些網絡請求可以提前到發起跳轉前一刻去請求。
    Taro 提供了 componentWillPreload 鈎子,它接收頁面跳轉的參數作為參數。可以把需要預加載的內容通過 return 返回,然后在頁面觸發 componentWillMount 后即可通過 this.$preloadData 獲取到預加載的內容。
class Index extends Component {
  componentWillMount () {
    console.log('isFetching: ', this.isFetching)
    this.$preloadData
      .then(res => {
        console.log('res: ', res)
        this.isFetching = false
      })
  }

  componentWillPreload (params) {
    return this.fetchData(params.url)
  }

  fetchData () {
    this.isFetching = true
    ...
  }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM