React Native新手求助:水平FlatList点击项底部边框切换实现
解决React Native水平FlatList选中项边框切换问题
嘿,我来帮你搞定这个问题!你现在遇到的核心问题是每个Category_style组件都维护着自己的Index状态,所以点击新项时,只有当前组件知道自己被选中了,其他组件根本不知道要取消自己的边框样式——这就是为什么旧选中项的边框不会消失。
解决办法很简单,我们需要把选中索引的状态提升到父组件Category中,让父组件统一管理所有子项的选中状态,这样所有Category_style组件都能共享同一个选中状态,自然就能正确切换边框了。
第一步:修改父组件Category的代码
我们需要在父组件里添加选中状态,并给子组件传递状态和点击回调:
static navigationOptions = { headerStyle: { backgroundColor: '#4caf50' }, headerTitle: <Text style={Category_in_style.headerTitleStyle}>Category</Text> } // 初始化状态,添加选中索引 state = { main_categories: [], // 你的原有数据 articles: [], // 你的原有数据 selectedCategoryIndex: 0 // 新增:默认选中第一个分类 } // 新增:处理分类点击的回调,更新选中索引 handleCategoryPress = (index) => { this.setState({ selectedCategoryIndex: index }); } renderCategory(item, index) { // 给子组件传递选中索引和点击回调 return ( <Category_style title={item.title} index={index} subCategory={item.sub_category} selectedIndex={this.state.selectedCategoryIndex} onCategoryPress={this.handleCategoryPress} /> ) } renderProduct(item) { return <Product_style image={item.imageUrl} title={item.title} price={item.price}/> } render() { return ( <View style={{backgroundColor: 'white'}}> <FlatList style={styles.first_flat} horizontal data={this.state.main_categories} renderItem={({item, index})=> this.renderCategory(item, index)} keyExtractor={(item, index) => index} /> <PTRView style={{backgroundColor: '#f1f1f1'}}> <FlatList style={[{marginTop: 10}, {marginBottom: 50}]} data={this.state.articles} renderItem={({item}) => this.renderProduct(item)} keyExtractor={(item, index) => index} numColumns={2} /> </PTRView> </View> ) }
第二步:修改子组件Category_style的代码
现在子组件不需要自己维护选中状态了,直接用父组件传递的props:
// 移除自己的Index状态,只保留模态框状态 state = { isModalVisible: false } _toggleModal = (index) => { // 点击时调用父组件的回调更新选中索引 this.props.onCategoryPress(index); this.setState({isModalVisible: !this.state.isModalVisible}); } renderProduct(item) { return <Sub_Categories_FlatList_style name={item.title} icon={item.icon}/> } renderSeparator = () => ( <View style={{ backgroundColor: '#d2d2d2', height: 0.5, }} /> ) render() { const {title, index, selectedIndex} = this.props; // 用父组件传递的selectedIndex和当前index对比,判断是否显示边框 const isSelected = index === selectedIndex; return ( <View style={pStyles.container}> <TouchableHighlight onPress={() => this._toggleModal(index)} style={isSelected ? pStyles.border_bottom : pStyles.no_border_bottom} > <Text style={pStyles.title}>{title}</Text> </TouchableHighlight> <Modal isVisible={this.state.isModalVisible} animationType={'slide'}> <TouchableOpacity onPress={() => this._toggleModal(index)} style={pStyles.T_opacity} activeOpacity={.7} > <Image source={require('./../pictures/x_icon.png')} style={pStyles.close_image}/> </TouchableOpacity> <View style={pStyles.in_modal_view}> <Text style={pStyles.modal_header_text}>{title}</Text> <FlatList data={this.props.subCategory} renderItem={({item}) => this.renderProduct(item)} ItemSeparatorComponent={this.renderSeparator} keyExtractor={(item, index) => index} /> </View> </Modal> </View> ) }
为什么这样改?
这是React里非常经典的状态提升模式:当多个组件需要共享状态或者状态需要在组件间同步时,把状态放到它们共同的父组件中管理,通过props把状态和回调传递给子组件,这样就能实现统一的状态控制,避免每个子组件各自为政的问题。
现在你再点击水平FlatList的项,就能看到当前选中项显示底部边框,上一个选中项的边框自动消失啦!
内容的提问来源于stack exchange,提问作者shahab
相关产品推荐
相关产品推荐

