我可以通过道具传递对象的名称以使用吗?
Posted
技术标签:
【中文标题】我可以通过道具传递对象的名称以使用吗?【英文标题】:Can I pass name of object to use through props? 【发布时间】:2017-05-09 04:48:01 【问题描述】:我想要完成的是:我创建了基于 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 是从样式对象应用的。我只想传递一个单词('black', 'white')来引用 Button 组件中描述的其他样式对象。
我知道我可以使用 switch 创建一个辅助方法,但我认为有一种更短的方法可以做到这一点。有吗?
非常感谢!
【问题讨论】:
如果只有一个样式,则不需要将样式放入数组中 也许这篇文章会对你有所帮助。 ***.com/a/31638988/4361743 我会基于 Button 制作单独的组件 WhiteButton 和 BlackButton,因此您的 Button 组件将保持干净,除了它自己的逻辑之外的任何其他逻辑。更好的名称将是 PrimaryButton 和 SecondaryButton,而不是使其名称特定于其样式。按钮组件将提供按钮的基本功能——它可以被按下,容器和文本可以以任何方式设置样式。您将能够重用它来创建更复杂的组件,因为可以按下很多东西,但它们看起来可能非常不同。 @DominicTobias 谢谢。我也只是在玩黑白风格。 @karman 谢谢! 【参考方案1】:我认为这将是最短和最干净的方式
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 不是必需的属性,则添加 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']),
;
【讨论】:
感谢您的帮助。我将使用这个解决方案。你能解释一下,块 Button.propTypes = ... 做什么?我试过在没有它的情况下这样做,它仍然可以正常工作。此外,“isRequired”有什么变化?我的意思是无论我是否需要它,如果我通过 'blaaack' 或根本没有通过,我仍然会看到应用程序崩溃,即如果它未定义。 很好,该解决方案很有用。您应该始终将 propTypes 添加到您的 React 组件中,以便其他开发人员看到该组件应该接收什么样的数据。您绝对应该阅读这篇文章,因为每个 React 开发人员都必须使用 propTypes facebook.github.io/react/docs/typechecking-with-proptypes.html :)【参考方案2】:根据我对您的问题的理解,请看一下:-
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'
;
【讨论】:
【参考方案3】:你可以这样做:
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;
【讨论】:
以上是关于我可以通过道具传递对象的名称以使用吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 React 钩子,我如何更新通过道具传递给孩子的对象?
为啥 Vue 不读取我通过 PHP 作为道具传递的整个 JSON 对象?