Как предоставить данные API для реагирования на нативную карусель
Я работаю над родным новостным приложением React, мне нужно проанализировать данные из REST API и предоставить эти данные для привязки карусельного компонента.
snap-carousal имеет sliderEntry.js, который ожидает заголовок, подзаголовок, иллюстрацию в виде массива пар ключ-значение.
SliderEntry.js
import React, { Component, PropTypes } from 'react';
import { View, Text, Image, TouchableOpacity } from 'react-native';
import styles from '../styles/SliderEntry.style';
export default class SliderEntry extends Component {
static propTypes = {
title: PropTypes.string.isRequired,
subtitle: PropTypes.string,
illustration: PropTypes.string,
even: PropTypes.bool
};
render () {
const { title, subtitle, illustration, even } = this.props;
const uppercaseTitle = title ? (
<Text style={[styles.title, even ? styles.titleEven : {}]} numberOfLines={2}>{ title.toUpperCase() }</Text>
) : false;
return (
<TouchableOpacity
activeOpacity={0.7}
style={styles.slideInnerContainer}
onPress={() => { alert(`You've clicked '${title}'`); }}
>
<View style={[styles.imageContainer, even ? styles.imageContainerEven : {}]}>
<Image
source={{ uri: illustration }}
style={styles.image}
/>
<View style={[styles.radiusMask, even ? styles.radiusMaskEven : {}]} />
</View>
<View style={[styles.textContainer, even ? styles.textContainerEven : {}]}>
{ uppercaseTitle }
<Text style={[styles.subtitle, even ? styles.subtitleEven : {}]} numberOfLines={2}>{ subtitle }</Text>
</View>
</TouchableOpacity>
);
}
}
Мой API возвращает данные в другом формате, я должен установить переменную состояния, которая является массивом в формате, который ожидает sliderEntry.js, поэтому я создал новый массив и извлек заголовок, подзаголовок, иллюстрацию из ответа API и установил новый массив как записи переменных состояния.
import React from "react";
import Carousel from 'react-native-snap-carousel';
import { sliderWidth, itemWidth } from './styles/SliderEntry.style';
import SliderEntry from './components/SliderEntry';
import styles from './styles/index.style';
import { ENTRIES1, ENTRIES2 } from './static/entries';
export default class HomeScreen extends React.Component {
getSlides (entries) {
if (!entries) {
return false;
}
return entries.map((entry, index) => {
return (
<SliderEntry
key={`carousel-entry-${index}`}
even={(index + 1) % 2 === 0}
{...entry}
/>
);
});
}
constructor(props) {
super(props);
this.state = {entries: ENTRIES1,entries2:[]};
}
componentDidMount() {
this.load();
}
async load(){
try {
let response = await fetch('http://newstrack.com/api/get_category_posts?id=263');
let responseJson = await response.json();
var responseModified =[
{
title: 'jhbfb ombop',
subtitle: 'Lorem ipsum dolor sit amet et nuncat mergitur',
illustration: 'http://i.imgur.com/UYiroysl.jpg'
},
{
title: 'Earlier this morning, NYC',
subtitle: 'Lorem ipsum dolor sit amet',
illustration: 'http://i.imgur.com/UPrs1EWl.jpg'
},
{
title: 'White Pocket Sunset',
subtitle: 'Lorem ipsum dolor sit amet et nuncat ',
illustration: 'http://i.imgur.com/MABUbpDl.jpg'
},
{
title: 'Acrocorinth, Greece',
subtitle: 'Lorem ipsum dolor sit amet et nuncat mergitur',
illustration: 'http://i.imgur.com/KZsmUi2l.jpg'
},
{
title: 'The lone tree, majestic landscape of New Zealand',
subtitle: 'Lorem ipsum dolor sit amet',
illustration: 'http://i.imgur.com/2nCt3Sbl.jpg'
},
{
title: 'Middle Earth, Germany',
subtitle: 'Lorem ipsum dolor sit amet',
illustration: 'http://i.imgur.com/lceHsT6l.jpg'
}
];
for (var i = 0; i <8; i++) {
responseModified [i].title=responseJson.posts[i].title;
responseModified [i].subtitle=responseJson.posts[i].excerpt;
responseModified[i].illustration=
responseJson.posts[i].attachments[0].url;
}
this.setState({
entries: responseJson.posts,
entries2: responseModified
}, function() {
// do something with new state
});
} catch(error)
{
console.error(error);
}
}
render() {
return (
<Carousel
sliderWidth={sliderWidth}
itemWidth={itemWidth}
inactiveSlideScale={1}
inactiveSlideOpacity={1}
enableMomentum={true}
autoplay={true}
autoplayDelay={500}
autoplayInterval={2500}
containerCustomStyle={styles.slider}
contentContainerCustomStyle={styles.sliderContainer}
showsHorizontalScrollIndicator={false}
snapOnAndroid={true}
removeClippedSubviews={false}
>
{ this.getSlides(this.state.entries2) }
</Carousel>
);
}
}
Структура API:
{
"posts":[
{
"title": "We are not looking forward to forming new party",
"excerpt": "<p>Lucknow: Samajwadi Party patriarch Mulayam",
"attachments": [
{
"url": "http:\/\/abc.com\/wp-content.jpg",
}
]
},
{
"title": "We are not looking forward to forming new party",
"excerpt": "<p>Lucknow: Samajwadi Party patriarch Mulayam",
"attachments": [
{
"url": "http:\/\/abc.com\/wp-content.jpg",
}
]
},
{
"title": "We are not looking forward to forming new party",
"excerpt": "<p>Lucknow: Samajwadi Party patriarch Mulayam",
"attachments": [
{
"url": "http:\/\/abc.com\/wp-content.jpg",
}
]
},
{...},
...
]
}
Я пытаюсь получить заголовок, отрывок, URL-адрес и присвоить title.subtitle, illustration. Это правильный способ сделать это? Я получаю ошибку:
undefined не является объектом (оценка 'responseModified[i].title=responseJson.posts[i].title')
1 ответ
Чтобы изменить массив, вы можете сначала создать пустой массив. лайк
var arrayModified = []
и после этого вы можете вставить значение в массив, как это
var array = responseJson.posts;
for (let i = 0; i < array.length; i++) {
if (arrayModified[0] === []) {
arrayModified.pop();
} else {
arrURI.push({
title: array[i].title,
subtitle: array[i].imageName,
illustration: array[i].imageData,
});
}
}
По моему мнению, это верный путь, и, возможно, после этого вы не получите ошибки недиффинда.