React Native自定义动画折叠组件开发问题求助
Fixing Your React Native Custom Collapsible Component Issues
Hey there! Let's work through the two problems you're hitting with your collapsible component. I've broken down the solutions below:
1. Clicking One Component Triggers All to Expand/Collapse
The root issue here is that all your collapsible items are sharing the same state (like expanded, animation) in the parent component. Each item needs its own independent state to control only itself.
Fix: Extract a Reusable CollapsibleItem Component
Move the state and toggle logic into a separate child component so each instance manages its own expansion state:
import React, { Component } from 'react'; import { View, Text, Animated, TouchableHighlight, Image, ScrollView } from 'react-native'; import { Card, CardSection } from './your-components-path'; // Adjust path to your Card components class CollapsibleItem extends Component { constructor(props) { super(props); this.icons = { 'up': require('../Images/Arrowhead.png'), 'down': require('../Images/Arrowhead-Down.png') }; this.state = { expanded: false, animation: new Animated.Value(0), maxHeight: 0, minHeight: 0 }; } toggle = () => { const { expanded, animation, maxHeight, minHeight } = this.state; const initialValue = expanded ? maxHeight + minHeight : minHeight; const finalValue = expanded ? minHeight : maxHeight + minHeight; this.setState({ expanded: !expanded }); animation.setValue(initialValue); Animated.spring(animation, { toValue: finalValue, useNativeDriver: false // Required for height animations in React Native }).start(); }; _setMaxHeight = (event) => { this.setState({ maxHeight: event.nativeEvent.layout.height }); }; _setMinHeight = (event) => { this.setState({ minHeight: event.nativeEvent.layout.height }); }; render() { const { curr } = this.props; const { expanded } = this.state; const icon = expanded ? this.icons['up'] : this.icons['down']; return ( <Animated.View style={[styles.container, { height: this.state.animation }]}> {curr.type === 'section' && ( <View onLayout={this._setMinHeight}> <Card> <CardSection> <TouchableHighlight onPress={this.toggle} underlayColor="#f1f1f1"> <Image style={styles.buttonImage} source={icon} /> </TouchableHighlight> <View style={styles.thumbnailContainerStyle}> <Text style={styles.userStyle1}>{curr.title}</Text> </View> </CardSection> </Card> </View> )} <View style={styles.body} onLayout={this._setMaxHeight}> {this.props.children} <Text>hiii</Text> </View> </Animated.View> ); } } // Parent component where you fetch and render data class CollapsibleContainer extends Component { constructor(props) { super(props); this.state = { details: [] }; } componentWillMount() { fetch('https://www.mywebsite.com') .then(response => response.json()) .then(responseData => this.setState({ details: responseData })); } render() { return ( <ScrollView> {this.state.details.map((detail, index) => detail.data.curriculum.map((curr, currIndex) => ( <CollapsibleItem key={`${index}-${currIndex}`} curr={curr}> {/* Insert your child content here */} </CollapsibleItem> )) )} </ScrollView> ); } } // Style definitions const styles = { container: { overflow: 'hidden', // Critical to clip content when collapsed marginVertical: 8, }, buttonImage: { width: 20, height: 20, resizeMode: 'contain' }, thumbnailContainerStyle: { marginLeft: 12, flex: 1 }, userStyle1: { fontSize: 16, fontWeight: '500' }, body: { padding: 12, backgroundColor: '#f8f8f8' } }; export default CollapsibleContainer;
2. Card Height Increases But Content Doesn't Show
This issue is tied to how your animated container handles overflow and animation targeting. Here are the key fixes:
- Add
overflow: 'hidden'to the animated container style (seestyles.containerabove) — this ensures content outside the animated height is hidden when collapsed, and visible when expanded. - The
Animated.Viewnow wraps both the header card and body content, so the height animation applies to the entire item's expandable area. - We added
useNativeDriver: falseto theAnimated.springcall — height animations can't use React Native's native driver, so this is required for the animation to work correctly.
Quick Additional Tips
- Always use unique
keyprops when mapping over arrays (like${index}-${currIndex}) to help React track component instances accurately. - Using arrow functions for event handlers avoids unnecessary re-renders caused by function binding in the render method.
内容的提问来源于stack exchange,提问作者Neethu M
相关产品推荐
相关产品推荐

