React Native多组件同名函数问题:react-native-material-menu弹窗异常
嘿,我一眼就看出问题所在了——你现在所有的Menu组件都共用了同一个_menu引用!FlatList在渲染每一条列表项时,setMenuRef都会把当前Menu的ref覆盖掉this._menu,到最后不管你点哪个菜单按钮,实际操作的都是最后渲染出来的那一个Menu实例,这就是为什么所有按钮都触发同一行为、打开同一个菜单的原因。
下面给你一套适配类组件的修复方案,分步骤来:
1. 重构ref存储方式
把原来单个的_menu变量改成一个对象,用来存储每个列表项对应的Menu ref,用item的唯一ID作为key:
// 替换原来的 _menu = null; _menus = {};
2. 修改ref赋值函数
让setMenuRef变成一个高阶函数,接收item的ID作为参数,返回一个真正的ref赋值函数,这样就能把每个Menu的ref对应到具体的item上:
setMenuRef = (itemID) => ref => { this._menus[itemID] = ref; };
3. 更新菜单显示/隐藏方法
让这两个方法也接收itemID参数,这样就能精准操作对应item的Menu:
hideMenu = (itemID) => { // 可选链操作符防止找不到对应ref时报错 this._menus[itemID]?.hide(); }; showMenu = (itemID) => { this._menus[itemID]?.show(); };
4. 调整FlatList里的Menu组件
把item的ID传递给ref、按钮的点击事件,还有每个MenuItem的点击事件:
<FlatList data={this.state.clientsList} renderItem={({ item }) => { return ( <View style={styles.caseItem} > <Card style={styles.card}> <CardItem> <Body> <View style={styles.rowTitle}> <Text style={styles.title}>{item.FullName}</Text> <Menu ref={this.setMenuRef(item.ID)} button={ <Icon type="Feather" name="more-vertical" onPress={() => this.showMenu(item.ID)} style={{fontSize:20,color:'#555'}} /> }> <MenuItem onPress={() => this.hideMenu(item.ID)}>View</MenuItem> <MenuItem onPress={() => { this.hideMenu(item.ID); // 这里可以添加Edit的具体逻辑,比如传入当前item this.handleEdit(item); }}>Edit</MenuItem> <MenuItem onPress={() => { this.hideMenu(item.ID); this.handleDelete(item.ID); }}>Delete </MenuItem> </Menu> </View> <View> <Text style={styles.lbl}>Email: <Text style={styles.lblValue}>{item.EmailID}</Text></Text> <Text style={styles.lbl}>Client Type: <Text style={styles.lblValue}>{item.ClientType}</Text></Text> </View> </Body> </CardItem> </Card> </View> ); }} keyExtractor={item => item.ID} />
额外优化:清理refs防止内存泄漏
在组件卸载时清空_menus对象,避免不必要的内存占用:
componentWillUnmount() { this._menus = {}; }
这样修改后,每个列表项的Menu都有了独立的引用,点击对应按钮只会触发当前item的菜单操作,不会再出现所有菜单共用一个实例的问题啦。
内容的提问来源于stack exchange,提问作者Zain Khan
相关产品推荐
相关产品推荐

