Проблема с выводом массива
Я пытаюсь вывести на экранную форму массив данных типа Structure. Проблема в том, что я не могу разобраться как выводить массив с данной структурой, где для каждого объекта есть массив systems. Выглядеть это должно примерно как SectionList, но при этом как для header, так и для item это должна быть строка из нескольких данных.
При реализации основывалась на данном примере https://reactnativedev.ru/rn/sectionlist/#_1
На данный момент форма падает со следующей ошибкой:
(NOBRIDGE) ERROR Warning: TypeError: Cannot read property 'length' of undefined
Запрос уходит корректно, возвращает данные, типы данных data и json совпадают. Но возможно проблема также в объявлении в Structure "подмассива" systems?
До этого пыталась выводить через вложенный flatlist, но данные из systems не выводились.
import { SectionList, Text, TouchableOpacity, View } from 'react-native'
import { router } from 'expo-router';
type Structure = {
id: number;
comments: number;
status: string;
systems:[
id: number,
numberII: string,
systemName: string,
],
};
const Struct = () => {
const [data, setData] = useState<Structure[]>([]);
const getStructure = async () => {
try {
const response = await fetch('https://...');
const json = await response.json();
setData(json);
console.log('ResponseSeeStructure:', response);
} catch (error) {
console.error(error);
} finally {
}
};
useEffect(() => {
getStructure();
}, []);
//const font16 = MonoSizeText(16);
return(
<SectionList
sections = {data}
keyExtractor={({id}) => id}
renderSectionHeader={({section: {comments, status}}) => (
<View style={{flexDirection: 'row', width: '100%', height: 32, paddingTop: 6, marginBottom: '3%', alignSelf: 'center', }}>
<View style={{width: '23%'}}>
<Text style={{ fontSize: 14, color: '#334155', textAlign: 'center' }}>{comments}</Text>
</View>
<View style={{width: '42%'}}>
<Text style={{ fontSize: 14, color: '#334155', textAlign: 'center' }}>{status}</Text>
</View>
</View>
)}
renderItem={({item: {systems}}) => (
<TouchableOpacity onPress={() =>{ router.push('/structures/system')}}>
<View style={{ alignSelf: 'center', backgroundColor: '#E0F2FE', flexDirection: 'row', width: '98%', height: 32, marginBottom: 41, borderRadius: 8}}>
<View style={{width: '10%', justifyContent: 'center',}}>
<Text style={{ fontSize:14, color: '#334155', textAlign: 'center' }}>{systems.numberII}</Text>
</View>
<View style={{width: '25%', justifyContent: 'center',}}>
<Text style={{ fontSize: 14, color: '#334155', textAlign: 'center' }}>{systems.systemName}</Text>
</View>
</View>
</TouchableOpacity>
)}
/>
);
};
export default Struct;```
Ответы (1 шт):
В документации для renderItem сказано: 'item' (объект) — объект элемента, указанный в ключе data этого раздела.
Поэтому у объекта должен быть массив data, и никак по другому не должен называться. Это непривычное поведение, но это так работает.
Ниже добавил измененный код, у меня работает. Если переименовать data
в systems
, то будет ошибка Cannot read property 'length' of undefined
import React, {useState} from 'react';
import {
StyleSheet,
Text,
View,
SafeAreaView,
SectionList,
StatusBar,
TouchableOpacity
} from 'react-native';
const DATA= [{
"id": 1,
"comments": 2,
"status" : "success",
"data": [ // только data, systems или другое название поля не подойдет
{
"id": 1,
"numberII" : "01",
"systemName": "name"
}
]
}];
const App = () => (
<SectionList
sections = {DATA}
keyExtractor={({id}) => id}
renderSectionHeader={({section: {comments, status}}) => (
<View style={{flexDirection: 'row', width: '100%', height: 32, paddingTop: 6, marginBottom: '3%', alignSelf: 'center', }}>
<View style={{width: '23%'}}>
<Text style={{ fontSize: 14, color: '#334155', textAlign: 'center' }}>{comments}</Text>
</View>
<View style={{width: '42%'}}>
<Text style={{ fontSize: 14, color: '#334155', textAlign: 'center' }}>{status}</Text>
</View>
</View>
)}
renderItem={({item}) => (
<TouchableOpacity onPress={() =>{ router.push('/structures/system')}}>
<View style={{ alignSelf: 'center', backgroundColor: '#E0F2FE', flexDirection: 'row', width: '98%', height: 32, marginBottom: 41, borderRadius: 8}}>
<View style={{width: '10%', justifyContent: 'center',}}>
<Text style={{ fontSize:14, color: '#334155', textAlign: 'center' }}>{item.numberII}</Text>
</View>
<View style={{width: '25%', justifyContent: 'center',}}>
<Text style={{ fontSize: 14, color: '#334155', textAlign: 'center' }}>{item.systemName}</Text>
</View>
</View>
</TouchableOpacity>
)}
/>
);
export default App;