【问题标题】: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 创建一个辅助方法,但我认为有一种更短的方法可以做到这一点。有吗?

非常感谢!

【问题讨论】:

  • 如果只有一个样式,则不需要将样式放入数组中
  • 也许这篇文章会对你有所帮助。 stackoverflow.com/a/31638988/4361743
  • 我会基于 Button 制作单独的组件 WhiteButton 和 BlackButton,因此您的 Button 组件将保持干净,除了它自己的逻辑之外的任何其他逻辑。更好的名称将是 PrimaryButton 和 SecondaryButton,而不是使其名称特定于其样式。按钮组件将提供按钮的基本功能——它可以被按下,容器和文本可以以任何方式设置样式。您将能够重用它来创建更复杂的组件,因为可以按下很多东西,但它们看起来可能非常不同。
  • @DominicTobias 谢谢。我也只是在玩黑白风格。
  • @karman 谢谢!

标签: javascript reactjs react-native ecmascript-6


【解决方案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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 2019-04-28
      • 2017-10-09
      相关资源
      最近更新 更多