React 17+TypeScript中如何为map()设置索引范围渲染指定汽车数据?
如何为map()设置索引范围,仅渲染指定ID区间的汽车数据?
需求:在@react-pdf/renderer 2.3.0中,使用<View>和<Text>组件渲染汽车数据时,不需要渲染全部5条数据,仅渲染id为2到4的条目。当前技术栈为TypeScript + React 17.0.2。
原始渲染全部数据的代码:
{ "cars": [ { "id": "0", "brand": "Toyota", "type": "Corolla", "color": "white" }, { "id": "1", "brand": "Mazda", "type": "CX-30", "color": "red" }, { "id": "2", "brand": "Honda", "type": "Civic", "color": "brown" }, { "id": "3", "brand": "Audi", "type": "A6", "color": "black" }, { "id": "4", "brand": "Mercedes", "type": "GLC", "color": "grey" } ], "total": 5 } {data?.cars.map((car: any, index: number) => { return ( <View key={index} > <Text>{index + 1}</Text> <Text>{car.brand || ""}</Text> <Text>{car.type || ""}</Text> <Text>{car.color || ""}</Text> </View> ) })}
尝试用for循环实现时出现「Unreachable code」错误:
{(() => { return ( for (let j = 2; j < 5; j++) { // <--- Unreachable code <View key={j} > <Text>{j + 1}</Text> <Text>{car.brand || ""}</Text> <Text>{car.type || ""}</Text> <Text>{car.color || ""}</Text> </View> } ) })()}
可行解决方案
方案1:使用slice()截取数组范围后再map
如果数组的索引和目标id完全对应(如本例中id=2对应数组索引2),可以直接用slice(startIndex, endIndex)截取需要的区间,再调用map渲染。注意slice的第二个参数是不包含的结束索引,所以要取到索引4的话,结束值设为5。
{data?.cars.slice(2, 5).map((car: any) => { return ( <View key={car.id} // 优先用唯一id作为key,比索引更稳定 > <Text>{parseInt(car.id) + 1}</Text> <Text>{car.brand || ""}</Text> <Text>{car.type || ""}</Text> <Text>{car.color || ""}</Text> </View> ) })}
方案2:使用filter()过滤指定ID区间后再map
如果数组索引和id不对应(比如id不是连续数字),可以用filter先筛选出符合id范围的条目,再进行渲染:
{data?.cars.filter(car => { const carId = parseInt(car.id); return carId >= 2 && carId <= 4; }).map((car: any) => { return ( <View key={car.id} > <Text>{parseInt(car.id) + 1}</Text> <Text>{car.brand || ""}</Text> <Text>{car.type || ""}</Text> <Text>{car.color || ""}</Text> </View> ) })}
方案3:修正for循环的写法
JSX中不能直接将for循环作为返回值(因为for是语句而非表达式),需要先创建一个数组存储渲染元素,再返回这个数组:
{(() => { const elements = []; const targetCars = data?.cars || []; for (let j = 2; j < 5; j++) { const car = targetCars[j]; if (!car) continue; // 防止数组越界 elements.push( <View key={car.id} > <Text>{j + 1}</Text> <Text>{car.brand || ""}</Text> <Text>{car.type || ""}</Text> <Text>{car.color || ""}</Text> </View> ); } return elements; })()}
内容的提问来源于stack exchange,提问作者Elo
相关产品推荐
相关产品推荐

