BensonLiao/liff-react-boilerplate

重構 `src/pages/SendMessage.js`

Closed this issue · 0 comments

關於 src/pages/SendMessage.js
有些想法,供參考

import absolute path

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import liffHelper from '../utils/liffHelper'
import messageHelper from '../utils/messagingApiHelper'
import swal from 'sweetalert2'
import { geolocated } from 'react-geolocated'

// 絕對路徑的 import 優先
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import swal from 'sweetalert2'
import { geolocated } from 'react-geolocated'
import liffHelper from '../utils/liffHelper'
import messageHelper from '../utils/messagingApiHelper'

縮排方式

          <label 
          htmlFor={`msg_${messageType.key}`} 
          className="message-label">

// after
          <label 
            htmlFor={`msg_${messageType.key}`} 
            className="message-label"
          >

render() 裡面的 let formGroups = ...

這個情境不需要用 let,看邏輯可以用 const。不過我想整段建議改法

有兩種改法,看你個人偏好

  1. 直接拉到 render 的 return 裡面
<div className="col-lg-6">
      {formGroups}  <== 這邊放進去就好了
      <hr />
      <button 
          type="button" 
      //....

// after
<div className="col-lg-6">
  {messageTypes.map((messageType, index) => (  
    <div className="form-group" key={messageType.key}> // <<== 正常情況,index 不能當作 react  key。因為只要順序一改動,所有後續的 element react 會視為有變動,然後全部重新 render。(這點如果不清楚,下次提醒我講一次範例
         //...
      </div>
  )}
  <hr />
  1. 把這段抽出去
    嫌上面的改法讓那邊太亂、太擠的話,可以考慮抽出去(抽到 render 之外)
      <div className="col-lg-6">
          {this.renderMessageTypes()}
          <hr />

// 另外在上面宣告
renderMessageTypes() {
  return (messageTypes.map((messageType, index) => (
    <div className="form-group" key={messageType.key}> 
     //...
    </div>
  )
}

PropTypes

這是對 props 做規範,不是對 state or this.func

SendMessage.PropTypes = {
  textInput: PropTypes.array.isRequired,
  setTextInputRef: PropTypes.func.isRequired,
}

// 應該是這幾個
SendMessage.PropTypes = {
  isGeolocationAvailable: ,
  isGeolocationEnabled: ,
  coords: ,
}

constructor

這段我看比較衝忙,沒時間看完整段邏輯,所以你改完可能要測試看看
基本上,如果沒有 state 的話(更精的話是說,沒有state 要用到 props 的話)(& 沒有要用到 bind 宣告的話,constructor 可以省略了。

這邊的 textInput 不是 state ,不應該放裡面。
setTextInputRef 的宣告方式

  constructor(props) {
    super(props)

    this.textInput = []

    this.setTextInputRef = (key, element) => {
      this.textInput[key] = element
    }
  }

// after
  constructor(props) {
    super(props)
    this.setTextInputRef = this.setTextInputRef.bind(this)
  }

   textInput = []
   setTextInputRef(key, element) =>  this.textInput[key] = element