反应原生:渲染用户点击的卡片

时间:2018-01-12 03:03:26

标签: reactjs react-native

我正在使用React Native代码,该代码使用map函数在数组上呈现“cards”。每张卡都包含在touchableOpacity组件中,因此当用户点击卡片时,它会翻转。目前的问题是,如果用户点击翻转一张卡,所有相邻的卡也会翻转。我希望每张卡的翻转功能都是独立的。当卡被翻转时,它也不应该触发相邻卡的翻转。提前感谢阅读本文。

class SavedBooks extends Component {
    componentWillMount() {
        this.animatedValue = new Animated.Value(0);
        this.value = 0;
        this.animatedValue.addListener(({ value }) => { this.value = value })
    }

    frontCardStyle() {
        this.frontInterpolate = this.animatedValue.interpolate({
            inputRange: [0, 180],
            outputRange: ['0deg', '180deg']
        })

        const frontAnimatedStyle = {
            transform: [ { rotateY: this.frontInterpolate }]
        }

        return frontAnimatedStyle
    }

    backCardStyle() {
        this.backInterpolate = this.animatedValue.interpolate({
            inputRange: [0, 180],
            outputRange: ['180deg', '360deg']
        })

        const backAnimatedStyle = { transform: [{ rotateY: this.backInterpolate }] }
        return backAnimatedStyle
    }

    flipCard() {
        if (this.value >= 90) {
            Animated.spring(this.animatedValue, {
                toValue: 0,
                friction: 8,
                tension: 10
            }).start();
        } else if (this.value < 90) {
            Animated.spring(this.animatedValue, {
                toValue: 180,
                friction: 8,
                tension: 10
            }).start();
        }
    }


    renderElemets(color) {
        const { savedBooks } = this.props.book 
        return savedBooks.map((book, index) => {
            return (
            <View
                key={index}
                style={{ alignItems: 'center' }}>

                <TouchableOpacity onPress={() => this.flipCard()} >
                    <Text
                        style={{ fontFamily: 'Helvetica', 
                        fontSize: 25, 
                        padding: 15 }}>
                        {book.title}
                    </Text>
                    <Animated.View>
                        <Animated.Image
                            style={[this.frontCardStyle(), styles.cardStyle]}
                            source={{ uri: book.image }}
                        />
                            <Animated.View style={[this.backCardStyle(), styles.cardStyle, styles.flipCardBack]}>
                            <Text>{book.description}</Text>
                        </Animated.View>
                    </Animated.View>
                </TouchableOpacity>
            </View>
            )
        });
    }

    render() {
        return (
            <ScrollView>
                {this.renderElemets(color)}
            </ScrollView>
            );
        }
}



const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#FFF',
    },
    imageStyle: {
        position: 'absolute',
        top: 0,
        left: 0,
        bottom: 0,
        right: 0,
    },
    cardStyle: {
        height: 400,
        width: 250,
        backfaceVisibility: 'hidden',
    },
    flipCardBack: {
        position: "absolute",
        top: 0,
    },
});

2 个答案:

答案 0 :(得分:1)

因为所有的卡都有相同的风格。你应该创建一个卡组件,这样每张卡都可以有自己的风格,而新闻事件不会影响其他卡。

答案 1 :(得分:0)

我遇到了这个问题并通过向数组中单击的项添加标识符或标记等内容来解决它。这个想法非常类似于添加一个类“活跃”的课程。单击数组中的项目,这样您的flipCard()函数将只在已标记为活动的项目上运行。简而言之,只需将frontCardStyle()或backCardStyle()添加到已单击并标记为“活动”的项目中。这样只有活动项才会翻转。 我按照这个example并提出了以下解决方案;

&#13;
&#13;
constructor(props) {
  super(props);

  this.state = {
    activeItem: {},
  }

  this.toggleActiveItem = this.toggleActiveItem.bind(this);
}

toggleActiveItem(index) {
  this.setState({
    activeItem: {
      [index]: true
    }
  });
  this.flipCard();
}

renderElemets(color) {
        const { savedBooks } = this.props.book 
        return savedBooks.map((book, index) => {
            return (
            <View
                key={index}
                style={{ alignItems: 'center' }}>

                <TouchableOpacity onPress={() => this.toggleActiveItem(index)} >
                    <Text
                        style={{ fontFamily: 'Helvetica', 
                        fontSize: 25, 
                        padding: 15 }}>
                        {book.title}
                    </Text>
                    <Animated.View>
                        <Animated.Image
                            style={[this.state.activeItem[index] && this.frontCardStyle(), styles.cardStyle]}
                            source={{ uri: book.image }}
                        />
                            <Animated.View style={[this.state.activeItem[index] && this.backCardStyle(), styles.cardStyle, styles.flipCardBack]}>
                            <Text>{book.description}</Text>
                        </Animated.View>
                    </Animated.View>
                </TouchableOpacity>
            </View>
            )
        });
    }
&#13;
&#13;
&#13;