2016-12-23 51 views
3

我想要完成的是:我已經創建了基於TouchableOpacity的按鈕組件。在我的應用程序中,我有3種類型的不同外觀的按鈕,它們都共享一些樣式,並具有特定的內容。下面是我Button.js看起來像:我可以通過道具傳遞物品名稱嗎?

import React, { Component } from 'react'; 
import { Text, TouchableOpacity } from 'react-native'; 

class Button extends Component { 
    render() { 
    const { children, onPress, style } = this.props; 
    const { buttonStyle, textStyle } = styles; 

    return (
     <TouchableOpacity onPress={onPress} style={[buttonStyle]}> 
     <Text style={[textStyle]}> 
      {children} 
     </Text> 
     </TouchableOpacity> 
    ); 
    } 
} 

//Commonly shared button styles 
const styles = { 
    textStyle: { 
    alignSelf: 'center', 
    fontSize: 17, 
    paddingTop: 15, 
    paddingBottom: 15 
    }, 
    buttonStyle: { 
    alignSelf: 'stretch', 
    marginLeft: 15, 
    marginRight: 15 
    } 
}; 

//Below are specific appearance styles 
const black = { 
    container: { 
    backgroundColor: '#000' 
    }, 
    text: { 
    color: '#FFF' 
    } 
}; 

const white = { 
    container: { 
    backgroundColor: '#FFF' 
    }, 
    text: { 
    color: '#000' 
    } 
}; 

這將是巨大的,如果我可以使用這個按鈕是這樣的:

<Button onPress={} style='black'>PLAY</Button> 
<Button onPress={} style='white'>CANCEL</Button> 

即默認的buttonStyle和textStyle是從樣式對象中應用的。我只想傳遞一個單詞('黑色','白色')來引用Button組件中描述的其他樣式對象。

我知道我可以用開關創建一個輔助方法,但我認爲有一個更簡單的方法來做到這一點。在那兒?

非常感謝!

+0

你不需要把你的樣式放在一個數組中,如果它只有一個 –

+0

可能這個帖子會幫助你。 http://stackoverflow.com/a/31638988/4361743 – karman

+0

我會製作單獨的組件WhiteButton和BlackButton,基於Button,所以你的Button組件將保持除了它自己以外的任何其他邏輯。即使更好的名字是PrimaryButton和SecondaryButton不要使他們的風格特定的名稱。按鈕組件將提供按鈕的基本功能 - 可以按下它,容器和文本可以以任何方式進行樣式設置。您可以重複使用它來創建更復雜的組件,因爲可以壓制很多東西,但它們看起來可能非常不同。 –

回答

2

我認爲這將是最短的和乾淨的way

import React, { PropTypes } from 'react'; 
import { Text, TouchableOpacity } from 'react-native'; 

const Button = ({ children, onPress, type }) => (
    <TouchableOpacity onPress={onPress} style={[styles.defaultButton, styles[type].button]}> 
    <Text style={[styles.defaultText, styles[type].text]}> 
     {children} 
    </Text> 
    </TouchableOpacity> 
); 

Button.propTypes = { 
    children: PropTypes.node.isRequired, 
    onPress: PropTypes.func.isRequired, 
    type: PropTypes.oneOf(['white', 'black']).isRequired, 
}; 

const styles = { 
    defaultButton: { 
    alignSelf: 'stretch', 
    marginLeft: 15, 
    marginRight: 15 
    }, 
    defaultText: { 
    alignSelf: 'center', 
    fontSize: 17, 
    paddingTop: 15, 
    paddingBottom: 15 
    }, 
    white: { 
    button: { 
     backgroundColor: '#FFF' 
    }, 
    text: { 
     color: '#000' 
    } 
    }, 
    black: { 
    button: { 
     backgroundColor: '#000' 
    }, 
    text: { 
     color: '#FFF' 
    } 
    }, 
}; 

export default Button; 

添加type && style[type].button如果類型不是必需的道具。像這樣:

const Button = ({ children, onPress, type }) => (
    <TouchableOpacity onPress={onPress} style={[styles.defaultButton, type && styles[type].button]}> 
    <Text style={[styles.defaultText, type && styles[type].text]}> 
     {children} 
    </Text> 
    </TouchableOpacity> 
); 

Button.propTypes = { 
    children: PropTypes.node.isRequired, 
    onPress: PropTypes.func.isRequired, 
    type: PropTypes.oneOf(['white', 'black']), 
}; 
+0

感謝您的幫助。我將使用這個解決方案。你能解釋一下,Button.propTypes = {...}塊是做什麼的?我試過沒有它,它仍然正常工作。而且,'需求'是什麼變化?我的意思是我是否有必要,如果我通過'blaaack'或者什麼都沒有通過,我仍然會看到應用程序崩潰,即如果它未定義。 – vad7mir

+0

好的解決方案是有用的。您應該始終將propType添加到您的React組件,以便其他開發人員查看組件應該接收的數據類型。你一定要讀這個,因爲每個React開發者都必須使用propTypes https://facebook.github.io/react/docs/typechecking-with-proptypes.html :) –

1

按我對你的問題的理解,請看看這個: -

var styleChangeForButton,styleChangeForText 
class Button extends Component { 
    constructor(props) 
    { 
    super(props) 
    const { children, onPress, style } = this.props; 
    const { buttonStyle, textStyle } = styles; 
    styleChangeForButton = [buttonStyle] 
    styleChangeForText = [textStyle] 

    } 
    onPress() 
    { 
     styleChangeForButton = 'black' 
     styleChangeForText = 'white' 
    } 

    render() { 

    // 

    style 
    return (
     <TouchableOpacity onPress={onPress} style={styleChangeForButton}> 
     <Text style={styleChangeForText}> 
      {children} 
     </Text> 
     </TouchableOpacity> 
    ); 
    } 
} 

//Commonly shared button styles 
const styles = { 
    textStyle: { 
    alignSelf: 'center', 
    fontSize: 17, 
    paddingTop: 15, 
    paddingBottom: 15 
    }, 
    buttonStyle: { 
    alignSelf: 'stretch', 
    marginLeft: 15, 
    marginRight: 15 
    } 
}; 

//Below are specific appearance styles 
const black = { 
    container: { 
    backgroundColor: '#000' 
    }, 
    text: { 
    color: '#FFF' 
    } 
}; 

const white = { 
    container: { 
    backgroundColor: '#FFF' 
    }, 
    text: { 
    color: '#000' 
    } 
}; 
1

你可以做這樣的事情:

import React, { PropTypes } from 'react'; 
import { StyleSheet, Text, TouchableOpacity } from 'react-native'; 

// Commonly shared button styles 
const defaultStyle = StyleSheet.create({ 
    textStyle: { 
    alignSelf: 'center', 
    fontSize: 17, 
    paddingTop: 15, 
    paddingBottom: 15, 
    }, 
    buttonStyle: { 
    alignSelf: 'stretch', 
    marginLeft: 15, 
    marginRight: 15, 
    }, 
}); 

// Below are specific appearance styles 
const black = StyleSheet.create({ 
    container: { 
    backgroundColor: '#000', 
    }, 
    text: { 
    color: '#FFF', 
    }, 
}); 

const white = StyleSheet.create({ 
    container: { 
    backgroundColor: '#FFF', 
    }, 
    text: { 
    color: '#000', 
    }, 
}); 

const themes = { 
    black, 
    white, 
}; 

function Button({ children, onPress, theme }) { 
    const buttonStyles = [defaultStyle.buttonStyle]; 
    const textStyles = [defaultStyle.textStyle]; 

    if (theme) { 
    buttonStyles.push(themes[theme].container); 
    textStyles.push(themes[theme].text); 
    } 

    return (
    <TouchableOpacity onPress={onPress} style={buttonStyles}> 
     <Text style={textStyles}> 
     {children} 
     </Text> 
    </TouchableOpacity> 
); 
} 

Button.propTypes = { 
    onPress: PropTypes.func.isRequired, 
    theme: PropTypes.string, 
    children: PropTypes.oneOfType([ 
    PropTypes.arrayOf(PropTypes.node), 
    PropTypes.node, 
    ]), 
}; 

export default Button; 
相關問題