You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native实现卡片图标单独控制对应List.Accordion的显隐

解决React Native中点击卡片图标仅切换对应List.Accordion显隐的问题

你的问题出在两处关键错误:

  1. 第二个版本中ButtonDetail的onPress写法错误:直接调用toggleAccordion(item.id)会在组件渲染时就执行函数,而非点击时触发,导致初始状态混乱。
  2. 所有List.Accordion共享同一个全局展开状态:breakfastExpanded是全局状态,不管点击哪个卡片,都会同步修改所有Accordion的展开状态。

下面是修正后的完整代码,同时优化了状态管理逻辑:

export const CategoryScreen = ({ navigation }) => {
    const { loading, categoryList } = useContext(CategoryContext);
    // 用对象存储每个item的展开状态,键为item.id,值为布尔值
    const [expandedIds, setExpandedIds] = useState({});

    const toggleAccordion = (id) => {
        // 更新对应id的展开状态
        setExpandedIds(prevState => ({
            ...prevState,
            [id]: !prevState[id] // 未初始化的id默认是undefined,取反后为true
        }));
    };

    return (
        <SafeArea>
            {loading && (
                <LoadingContainer>
                    <ActivityIndicator animating={true} color={MD2Colors.green200} />
                </LoadingContainer>
            )}
            <Search />
            <CategoryList
                data={categoryList}
                renderItem={({ item }) => {
                    const isExpanded = expandedIds[item.id] || false;
                    return (
                        <>
                            <TouchableOpacity
                                onPress={() => navigation.navigate("groepen", { subcategories: item.id })}>
                                <Spacer position="top" size="large">
                                    <CategoryInfoCard category={item} />
                                </Spacer>
                            </TouchableOpacity>
                            <View>
                                {/* 用箭头函数包裹,确保点击时才触发toggle */}
                                <ButtonDetail onPress={() => toggleAccordion(item.id)}>
                                    <AntDesign name="twitter" size={24} color="green" />
                                </ButtonDetail>
                            </View>
                            {/* 直接渲染List.Accordion,用isExpanded控制展开状态,避免组件频繁挂载卸载 */}
                            <List.Accordion
                                title="Description"
                                left={(props) => <List.Icon {...props} icon="bird" />}
                                expanded={isExpanded}
                                {/* 点击Accordion本身也可以切换状态,复用toggle函数 */}
                                onPress={() => toggleAccordion(item.id)}>
                                <List.Item title={item.description} />
                            </List.Accordion>
                        </>
                    );
                }}
                keyExtractor={(item) => item.id}
            />
        </SafeArea>
    );
};

关键修改说明:

  • 状态管理优化:用expandedIds对象替代数组,直接映射每个item的id和展开状态,查询和更新更高效。
  • 修正onPress调用方式:用() => toggleAccordion(item.id)包裹,确保只有点击时才执行切换逻辑。
  • 每个Accordion独立控制:expanded属性绑定当前item对应的isExpanded状态,实现单独切换。
  • 移除冗余的显隐判断:直接渲染List.Accordion,用其自身的expanded属性控制展开/收起,比条件渲染更流畅。

内容的提问来源于stack exchange,提问作者mightycode Newton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:32:03