React Native时间按钮交互优化:修复循环渲染与点击响应问题
React Native时间按钮组件优化需求
我需要在React Native中渲染时间按钮组件,要求每个按钮点击时能独立响应。当前代码存在嵌套循环渲染问题(外层循环4次、内层12次),其中buka值为8,tutup值为20。需要让每个按钮具备交互性,并实现目标效果图的样式。
现有代码
for (let i = buka; i <= tutup; i++) { for (let j = 0; j < data.length; j++) { const item = data[j]; jam.push( <TouchableOpacity style={{ borderRadius: 16, backgroundColor: '#161616', width: 93, height: 77, justifyContent: 'center', alignItems: 'center', marginHorizontal: 17 / 2, marginVertical: 8, borderWidth: 2, borderColor: i === item.clock_time ? '#C4F601' : '#000000', }} key={i} onPress={handlePress[i]}> <View> <Text style={[styles.heading14, {color: '#FFFFFF'}]}>{i}.00</Text> <Text style={[styles.heading14, {color: '#FFFFFF', fontWeight: '400'}]}> {i === clockTime ? 'terisi' : 'tersedia'} </Text> </View> </TouchableOpacity>, ); } } return ( <View style={styles.container}> {jam.map((number, index) => ( <View key={index}>{number}</View> ))} </View>
当前渲染效果

目标渲染效果

解决方案
1. 修复嵌套循环重复渲染问题
现有嵌套循环会让每个时间点重复渲染data.length次,直接生成(tutup - buka + 1)个时间按钮即可,无需内层循环。若需用data标记按钮状态,在单循环内匹配对应数据即可。
2. 确保按钮独立交互与唯一Key
- 每个按钮的
key必须唯一,改用time-${i}作为标识,避免重复Key引发的渲染异常。 - 绑定
onPress时通过箭头函数传递当前时间参数,规避闭包导致的交互失效问题。
3. 样式与状态匹配优化
- 用
data.some()判断当前时间是否被占用,替换原有的i === clockTime错误匹配逻辑。 - 容器添加
flexWrap: 'wrap'和flexDirection: 'row',实现目标效果的横向自动换行布局。
优化后完整代码示例:
// 整理需渲染的时间列表 const timeList = []; for (let i = buka; i <= tutup; i++) { // 判断当前时间是否已被占用 const isOccupied = data.some(item => item.clock_time === i); timeList.push( <TouchableOpacity key={`time-${i}`} style={{ borderRadius: 16, backgroundColor: '#161616', width: 93, height: 77, justifyContent: 'center', alignItems: 'center', marginHorizontal: 17 / 2, marginVertical: 8, borderWidth: 2, borderColor: isOccupied ? '#C4F601' : '#000000', }} onPress={() => handlePress(i)} // 传递当前时间参数 > <View> <Text style={[styles.heading14, {color: '#FFFFFF'}]}>{i}.00</Text> <Text style={[styles.heading14, {color: '#FFFFFF', fontWeight: '400'}]}> {isOccupied ? 'terisi' : 'tersedia'} </Text> </View> </TouchableOpacity> ); } return ( <View style={[styles.container, {flexWrap: 'wrap', flexDirection: 'row'}]}> {timeList} </View> );
关键说明
- 移除内层循环,每个时间点仅生成一个按钮,解决重复渲染问题。
- 通过
data.some()精准匹配已占用时间,修正状态显示逻辑。 - 容器布局属性调整,实现目标效果的横向排列自动换行。
内容的提问来源于stack exchange,提问作者doni chrisdianto
相关产品推荐
相关产品推荐

