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

时间:2016-12-23 13:11:11

标签: javascript reactjs react-native ecmascript-6

我想要完成的是:我已经创建了基于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创建一个helper方法,但我认为有一个更短的方法可以做到这一点。有吗?

非常感谢!

3 个答案:

答案 0 :(得分:2)

我认为这将是最短最干净的方式

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']),
};

答案 1 :(得分: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'
  }
};

答案 2 :(得分: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;