简体   繁体   中英

React Native - FlatList rendering all of the items in one row repeatedly

On the previous screen, you can choose an episode. On this screen, episode ID coming from the previous screen and with this ID, its taking every character ID from API. Characters IDs are slicing from characters URLs. The problem is flatList rendering all of the characters in one row (in one button) repeatedly and stopping at the character that has the last id. How can I solve that?

Episode API: https://rickandmortyapi.com/api/episode/ Character API: https://rickandmortyapi.com/api/character/

 const EpisodeDetailScreen = (props) => { const { styles, colors } = useThemedValues(getStyles); const loc = useLocalization(); // character list for flatlist const [characterList, setCharacterList] = useState([ { "created": "", "episode": [""], "gender": "", "id": 0, "image": "", "location": { "name": "", "url": "" }, "name": "", "origin": { "name": "", "url": "" }, "species": "", "status": "", "type": "", "url": "" }, ]) // episode details const [episodeDetail, setEpisodeDetail] = useState([]) // this id come from previous screen const { episodeId } = props.route.params // details of a chosen episode from the previous screen useEffect(() => { Axios.get('episode/' + episodeId) .then(response => { let episodeDetail = response.data setEpisodeDetail(episodeDetail) // episode details //Getting the IDs of the characters in the section from the last part of the URLs in the incoming data // You can see in data example that for (var i = 0; i < episodeDetail.characters.length; i++) { const charactersUrlInEpisode = episodeDetail.characters[i] const splittedUrl = charactersUrlInEpisode.split("/"); const charactersIdInUrl = splittedUrl[splittedUrl.length - 1] // Extracting character ids and character details from API and throwing them into state takeCharacters(charactersIdInUrl) console.log(charactersIdInUrl) } }) .catch(error => { console.log(error) }) }, []) // function that pulls character details from api based on given id const takeCharacters = (id) => { Axios.get('character/' + id) .then(response => { let characterDetail = response.data setCharacterList([characterDetail]) }) .catch(error => { console.log(error) }) } const _renderCharactersItem = ({ item }) => { return ( <TouchableOpacity onPress={() => { props.navigation.navigate("character-detail-screen", { characterId: item.id }); }}> <View style={styles.characterButton}> <Text style={styles.characterNameText} numberOfLines={1}>{item.name}</Text> </View> </TouchableOpacity> ) } return ( <View style={styles.container}> <View style={styles.episodeNameContainer}> <Text style={styles.episodeNameText}>{episodeDetail.name}</Text> </View> <View style={styles.detailsContainer}> <Text style={styles.detailsText}>{loc.t(texts.episode)}{episodeDetail.episode}</Text> <Text style={styles.detailsText}>{loc.t(texts.airDate)} {episodeDetail.air_date}</Text> </View> <View style={styles.characterTitleContainer}> <Text style={styles.characterTitleText}>{loc.t(texts.characters)}</Text> </View> <FlatList data={characterList} renderItem={_renderCharactersItem} keyExtractor={item => item.id} style={styles.flatListContainer} /> </View> ); }; export default EpisodeDetailScreen;

FlatList style:

 import { StyleSheet } from 'react-native'; import { colorNames } from '../../Theming' import {Metrics, Fonts} from '../../../StylingConstants' const styles = (Colors) => StyleSheet.create({ flatListContainer: { flex:1, paddingHorizontal: Metrics.width * 0.05 }, characterButton:{ justifyContent:'center', alignItems:'center', backgroundColor: Colors[colorNames.home.buttonBackground], marginTop: Metrics.width / 24, borderWidth: Metrics.width / 72, borderRadius: Metrics.width / 20, borderColor: Colors[colorNames.home.buttonBorder] }, characterNameText:{ color: Colors[colorNames.home.episodeText], fontSize: Fonts.size(18), fontFamily: Fonts.type.bold, marginHorizontal: Metrics.width * 0.05, marginTop: Metrics.width / 36, marginBottom: Metrics.width / 30 }, }); export default styles;

You are replacing your charactersList on every iteration. You must do like this


    // function that pulls character details from api based on given id
    const takeCharacters = (id) => {
        Axios.get('character/' + id)
            .then(response => {
                let characterDetail = response.data
                setCharacterList(previousState => [...previousState,...characterDetail])
            })
            .catch(error => {
                console.log(error)
            })
    }

You got it? Please, if this code does not correct your problem, provide some prints of your screen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM