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中嘗試一波,結果:
秉着不拋棄不放棄的精神,為了少寫代碼讓我們低頭看報錯。
根據報錯第一條信息,此時鏡頭給到了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眾生受益。少寫代碼目標達成!!!