如何使此自定义按钮组件可在不同控件之间重复使用? [英] How can I make this custom button component reusable across different controls?
问题描述
我有这个自定义组件类,我将它应用到我的 React Native 按钮,它具有预期的缩放行为(添加动画以缩小和调整大小),这是我想要的行为.但是,我希望应用程序中的其他控件(例如 Cards)具有相同的动画.我想知道,如何更改这个类以使其更具可扩展性?
这是我的代码:
从react"导入React;import { StyleSheet, Text, TouchableWithoutFeedback, Animated} from "react-native";从./Colors"导入颜色;从./Fonts"导入字体;导出默认类 TouchableBounce 扩展 React.Component {构造函数(道具){超级(道具);this.handlePressIn = this.handlePressIn.bind(this);this.handlePressOut = this.handlePressOut.bind(this);}componentWillMount() {this.animatedValue = new Animated.Value(1);}手柄按下(){Animated.spring(this.animatedValue, {价值:0.5}).开始()}处理按输出(){Animated.spring(this.animatedValue, {值:1,摩擦力:5,张力:40}).开始()}使成为() {const 动画风格 = {变换:[{比例:this.animatedValue}]}常量{残疾,文本,颜色,背景颜色,风格,显示箭头,测试ID,按钮样式} = this.props;返回 (<TouchableWithoutFeedbackonPressIn={this.handlePressIn}onPressOut={this.handlePressOut}禁用={禁用}style={[styles.buttonContainer, style]}测试ID={测试ID ||`button_${text}`}><Animated.View风格={[样式按钮,禁用?{不透明度:0.5}:{},{ 背景颜色 },按钮样式,动画风格]}><Text style={[styles.buttonText, { color }]}>{text.toUpperCase()}</Text>{showArrow &&(<文本风格={{字体大小:20,fontWeight: "粗体",白颜色",fontFamily: "系统字体",边距底部:1}}>{" "}→</文本>)}</Animated.View></TouchableWithoutFeedback>);}}TouchableBounce.defaultProps = {禁用:假,颜色 : Colors.white,backgroundColor : Colors.mainAccent,风格 : {},显示箭头:假,测试 ID : "",按钮样式:{}}const 样式 = StyleSheet.create({按钮容器:{alignSelf: "伸展",边距顶部:35,底边距:35},按钮: {边界半径:4,填充:20,flexDirection: "行",alignItems: "中心",justifyContent:中心"},按钮文本:{文本对齐:居中",fontFamily:Fonts.montserratBold,字体大小:16}});
我有一个问题,我应该在哪里对嵌套组件进行更改.在我的主页渲染函数中有这个片段
const card = active ?(<ActiveCard购买={active}/>) : (<InactiveCard/>);
在我返回的渲染中,有这个片段
{!this.props.foo &&(<查看><TouchableOpacitytestID={"TOUCHABLE_CARD"}onPress={() =>{this.tapCard(活动);}}>{卡片}</TouchableOpacity></查看>)}
我应该在哪里包装 TouchableBounce?在这两个地方还是其中一个地方?
尝试将它们作为 TouchableBounce
<卡片视图/></TouchableBounce>
在 TouchableBounce 中将它们渲染为
为了清楚地理解我附上一个工作演示 Expo demo>
以及官方文档 React.Children
I have this custom component class that I apply to my React Native Buttons and it has the expected behavior of scaling in and out (adding animation to shrink and resize) which is the behavior I want. However, I want the same animation for other controls in my app like Cards for example. I was wondering, how can I change this class to make it more extensible?
Here's my code:
import React from "react";
import { StyleSheet, Text, TouchableWithoutFeedback, Animated} from "react-native";
import Colors from "./Colors";
import Fonts from "./Fonts";
export default class TouchableBounce extends React.Component {
constructor(props) {
super(props);
this.handlePressIn = this.handlePressIn.bind(this);
this.handlePressOut = this.handlePressOut.bind(this);
}
componentWillMount() {
this.animatedValue = new Animated.Value(1);
}
handlePressIn() {
Animated.spring(this.animatedValue, {
toValue: .5
}).start()
}
handlePressOut() {
Animated.spring(this.animatedValue, {
toValue: 1,
friction: 5,
tension: 40
}).start()
}
render() {
const animatedStyle = {
transform: [{ scale: this.animatedValue}]
}
const {
disabled,
text,
color,
backgroundColor,
style,
showArrow,
testID,
buttonStyle
} = this.props;
return (
<TouchableWithoutFeedback
onPressIn={this.handlePressIn}
onPressOut={this.handlePressOut}
disabled={disabled}
style={[styles.buttonContainer, style]}
testID={testID || `button_${text}`}
>
<Animated.View
style={[
styles.button,
disabled ? { opacity: 0.5 } : {},
{ backgroundColor },
buttonStyle,
animatedStyle
]}
>
<Text style={[styles.buttonText, { color }]}>{text.toUpperCase()}</Text>
{showArrow && (
<Text
style={{
fontSize: 20,
fontWeight: "bold",
color: "white",
fontFamily: "system font",
marginBottom: 1
}}
>
{" "}
→
</Text>
)}
</Animated.View>
</TouchableWithoutFeedback>
);
}
}
TouchableBounce.defaultProps = {
disabled : false,
color : Colors.white,
backgroundColor : Colors.mainAccent,
style : {},
showArrow : false,
testID : "",
buttonStyle : {}
}
const styles = StyleSheet.create({
buttonContainer: {
alignSelf: "stretch",
marginTop: 35,
marginBottom: 35
},
button: {
borderRadius: 4,
padding: 20,
flexDirection: "row",
alignItems: "center",
justifyContent: "center"
},
buttonText: {
textAlign: "center",
fontFamily: Fonts.montserratBold,
fontSize: 16
}
});
EDIT: I have a question on where I should make the change for nesting the component.Inside my Home render function there's this snippet
const card = active ? (
<ActiveCard purchase={active} />
) : (
<InactiveCard />
);
and inside my return of that render, there is this snippet
{!this.props.foo && (
<View>
<TouchableOpacity
testID={"TOUCHABLE_CARD"}
onPress={() => {
this.tapCard(active);
}}
>
{card}
</TouchableOpacity>
</View>
)}
Where should I wrap the TouchableBounce? In both places or one of those places?
Try passing them as children of TouchableBounce
<TouchableBounce>
<CardView/>
</TouchableBounce>
In the TouchableBounce render them as
<TouchableWithoutFeedback
onPressIn={this.handlePressIn}
onPressOut={this.handlePressOut}
disabled={disabled}
style={[styles.buttonContainer, style]}
testID={testID || `button_${text}`}
>
<Animated.View
style={[
styles.button,
disabled ? { opacity: 0.5 } : {},
{ backgroundColor },
buttonStyle,
animatedStyle
]}
>
{this.props.children}//Here is the cardview that you have sent
</Animated.View>
</TouchableWithoutFeedback>
Edit:
For clear understanding iam attaching a working demo Expo demo
and also the official docs React.Children
这篇关于如何使此自定义按钮组件可在不同控件之间重复使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!