我可以通过道具传递对象的名称以使用吗?

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 &amp;&amp; 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 对象?

我可以通过 props.children React JS 将道具传递给孩子吗

你可以将 props 传递给 JSX 引用吗?

传递返回对象道具后 v-select 规则不起作用

antd table 的分页道具