简体   繁体   中英

Undefined is not an object in React Native project but console.log shows value

I want to make transition view in my React Native project. In Picture component I always get error: undefined is not an object (evaluating 'info.images[0]'). When I console.log info.images[0] or info.images[0].image I got normal link for picture not undefined.

My FavouritePlaces.tsx component:

 const FavouritePlaces = ({navigation}: HomeNavigationProps<"FavouritePlaces">) => {
    const[markers, setMarkers] = useState([]);
    useEffect(() => {
        const getFavourites = async () => {
                let keys = []
                try {
                    keys = await AsyncStorage.getAllKeys()
                } catch (e) {
                    // read key error
                }
                let values
                try {
                    values = await AsyncStorage.multiGet(keys)
                    setMarkers(values)
                    console.log('ValuesFromAsyncStorage', values)
                } catch(e) {
                    // read error
                }
        }
        getFavourites();
    }, [])
    const transition = (
        <Transition.Together>
            <Transition.Out type='fade' />
            <Transition.In type='fade' />
        </Transition.Together>
    );

    const list = useRef<TransitioningView>(null);
    const theme = useTheme()
    const width = (wWidth - theme.spacing.m * 3) / 2;
    const [footerHeight, setFooterHeight] = useState(0);
    return (
        <Box flex={1} backgroundColor="background">
            <Header
                title="Избранные места"
                left={{icon: 'menu', onPress: () => navigation.openDrawer()}}
                right={{icon: 'shopping-bag', onPress: () => true}}
            />
            <Box flex={1}>
                <ScrollView contentContainerStyle={{
                    paddingHorizontal: theme.spacing.m,
                    paddingBottom: footerHeight
                }}>
                    <Transitioning.View ref={list} transition={transition}>
                        {markers ?
                        <Box flexDirection='row'>
                            <Box marginRight='s'>
                                {markers
                                    .filter((_, i) => i % 2 !== 0).map((currentMarker) => <Picture key={currentMarker}
                                                                                           place={currentMarker}
                                                                                           width={width}/>)}
                            </Box>
                            <Box>
                                {markers
                                    .filter((_, i) => i % 2 === 0).map((currentMarker) => <Picture key={currentMarker}
                                                                                                   place={currentMarker}
                                                                                                   width={width}/>)}
                            </Box>
                        </Box> : undefined}
                    </Transitioning.View>
                </ScrollView>
                <TopCurve footerHeight={footerHeight}/>
                <Box position='absolute' bottom={0} left={0} right={0} onLayout={({
                                                                                      nativeEvent: {
                                                                                          layout: {height},
                                                                                      }
                                                                                  }) => setFooterHeight(height)}>
                    
                    <Footer label="Удалить из избранного" onPress={() => {
                        list.current?.animateNextTransition();
                        // setPlaces(places.filter((place => !place.selected)))
                        // console.log(defaultPictures)
                    }}/>

                </Box>
            </Box>
        </Box>
    )
}
export default FavouritePlaces

Picture component:

const Picture = ({
                     place,
                     width
                 }: PictureProps) => {
    
    const info = JSON.parse(place[1])
    console.log('currentInfo', info.images[0].image)

    const [selected, setSelected] = useState(false);

     return (
                <BorderlessTap onPress={() => {
            setSelected(prev => !prev);
            place.selected = !place.selected;
        }}>
            {/*<Text>{place.description}</Text>*/}
                    {info.images[0].image ?
            <ImageBackground
                style={{backgroundColor: 'black', borderRadius: '3%', marginBottom: '3%', alignItems: 'flex-end', padding: '3%', width, height: 80}}
                             source={{ uri: info.images[0].image }}>
     
                {selected && (
                    <RoundedIcon
                        backgroundColor="primary"
                        color="background"
                        size={24} name="check"
                    />
                )}
            </ImageBackground> : undefined}
        </BorderlessTap>
    )
}

export default Picture

You are rendering the Picture component before getFavourites has populated markers.

Your logic markers? ... : undefined markers? ... : undefined is always going to be truthy because [] evaluates to true . You should do something like markers.length? ... : undefined markers.length? ... : undefined .

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