React style支持數組語法糖


React style支持數組語法糖探究

​使用react-native,挖土填坑,下一腳還是繼續踩坑。踩坑之余也發現了和react不同之處,或可稱之為小亮點。話說三句不能離代碼,請賞下文:

class demo extends Component {
    render() {
      const btnText = {
        fontSize: 30,
        color: '#757575'
      }
      const color = {
        color: '#FE2740'
      }
        return (
             <TouchableOpacity
                style={styles.wordContainer}
                activeOpacity={1}
                onPress={()=>this.props.showWordDialog(index, item)}>
                <Text style={
                 Object.assign({}, 
                     btnText,
                     item === selectedWord && color
                   )}
                  >
                     Button
                 </Text>
             </TouchableOpacity>
        )
    }
}

在rn中樣式通過style屬性,其實就是一個樣式對象,可以理解為內聯樣式。

常見的需求,靜態一套樣式,交互后需要修改樣式或者新增樣式。使用rn初期,便想到style支持對象,結合jsx特性,使用Object.assign進行淺拷貝,合成一個對象。

此種解決方案並無問題,使用良久,仍是不能習慣每次出現出現此類情況,需要格式代碼洋洋灑灑好幾行,懶惰使人進步,如何才能更少的代碼,行數實現?

直到某次項目預研時,發現了rn的神奇寫法(也許文檔翻的還是不夠爛,大佬勿噴),如下所示:

class demo extends Component {
    render() {
      const btnText = {
        fontSize: 30,
        color: '#757575'
      }
      const color = {
        color: '#FE2740'
      }
        return (
             <TouchableOpacity
                style={styles.wordContainer}
                activeOpacity={1}
                onPress={()=>this.props.showWordDialog(index, item)}>
                <Text style={[btnText, item === selectedWord && color}]}>
                    Button
                 </Text>
             </TouchableOpacity>
        )
    }
}

當你需要設置多個樣式時,rn style支持對象數組,你可以在里面增加判斷,乃至多個樣式對象,以最右側值優先。如此寫法又可以少敲多少代碼!!!

嘗到甜頭之后則想react是否可以實現一波,源碼扒一下,發現海量源碼難以下咽。轉念一想,先寫成數組,看看報錯會出在哪里?
立馬去react中嘗試一波,結果:

image-20200813212329670

秉着不拋棄不放棄的精神,為了少寫代碼讓我們低頭看報錯。

根據報錯第一條信息,此時鏡頭給到了react-dom中4619行的setValueForStyles方法,瞅瞅這命名基本了解一切有沒有,給styles設置值!!!上代碼:


    /**
     * Sets the value for multiple styles on a node.  If a value is specified as
     * '' (empty string), the corresponding style property will be unset.
     *
     * @param {DOMElement} node
     * @param {object} styles
     */

    function setValueForStyles(node, styles) {
      var style = node.style;

      for (var styleName in styles) {
        if (!styles.hasOwnProperty(styleName)) {
          continue;
        }

        var isCustomProperty = styleName.indexOf('--') === 0;

        {
          if (!isCustomProperty) {
            warnValidStyle$1(styleName, styles[styleName]);
          }
        }

        var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);

        if (styleName === 'float') {
          styleName = 'cssFloat';
        }


        if (isCustomProperty) {
          style.setProperty(styleName, styleValue);
        } else {
          style[styleName] = styleValue;
        }
      }
    }

從頭看這個函數,兩個參數node, styles,且第一行取的就是node.style,來我們猜猜這是不是我們傳進來的style。驗證結果沒錯,style傳入就是在這里。
這里將我們傳入的style進行拆分並驗證是否正確,而我們傳入的數組通過dangerousStyleValue的檢測返回對象,並不能最后用於樣式展示,所以最終引起報錯。

這里我們便理明白了react中style為什么不支持對象數組類型。接下來只需稍加修改便可達成我們最終目標:少寫代碼!!!
上代碼!!!

   function setValueForStyles(node, styles) {
      var style = node.style;

      if (Array.isArray(styles)) {
        styles = Object.assign({}, ...styles)
      }
      .....
   }

如上所示在拿到傳入的style之后進行類型檢測,如果為數組類型,就將數組內的對象通過Object.assign配合es6擴展運算符整合成一個styles對象進行后續處理。一次assign眾生受益。少寫代碼目標達成!!!


免責聲明!

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



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