使用条件渲染的 React Native 仍然尝试访问状态,即使设置为 false

问题描述

我正在尝试渲染一个组件,但只有在我收到服务器的响应之后。 出于某种原因,即使条件仍然为假,它看起来仍然试图安装组件。

我尝试在访问数组之前添加一些预检查,但错误仍然存​​在。见下面的代码

MyComponent.js

import React,{ useEffect,useState } from 'react'
import MapView,{ PROVIDER_GOOGLE } from 'react-native-maps'; // remove PROVIDER_GOOGLE import if not using Google Maps
import {StyleSheet,View,Text} from 'react-native'
import { Dimensions } from 'react-native';
import { Marker } from 'react-native-maps';
import { getCarpoolByCode } from '../../services/CarpoolRidesService';
import { connect } from 'react-redux';
import SimpleSpinner from '../global/SimpleSpinner';
import { TouchableOpacity } from 'react-native-gesture-handler';
import MapViewDirections from 'react-native-maps-directions';

const GOOGLE_MAPS_APIKEY = '...';

const Map = ({
    route,carpoolCode,token
}) => {

    const [markers,setMarkers] = useState([])
    const [loader,setLoader] = useState(false)
    const [path,setPath] = useState([])
    const [source,setSource] = useState([])
    const [dest,setDest] = useState([])

    useEffect(() => {
        setLoader(true)
        console.log(token)
        console.log(route.params?.carpoolCode)
        getCarpoolByCode(token,route.params?.carpoolCode)
            .then(res => {
                console.log("MapPPPPPPPPPP")
                console.log(res)
                setSource(res.source)
                setDest(res.destination)
                setPath(
                    [
                        res.source,...res.path,res.destination
                    ]
                )
                setLoader(false)
            })
            .catch(err => {
                console.log(err)
                setLoader(false)
            })
        // console.log(route.params)
        // setLoader(true)
        // setMarkers(route.params.results.map(it => it.carpoolData))
        // setLoader(false)
    },[])

    return (

        <>
                {
                    loader ? 
                    <SimpleSpinner/>
                    :
                    <View style={styles.container}>

                        {/* <TouchableOpacity onPress={() => console.log(path)} style={{flex:1}}>
                            <Text>sadas</Text>

                        </TouchableOpacity> */}


                    <MapView
                    provider={PROVIDER_GOOGLE} 
                    style={styles.map}
                    region={{
                        latitude:  path ? path[0][0] : 0,longitude: path ? path[0][1] : 0,latitudeDelta: 0.015,longitudeDelta: 0.0121,}}
                    showsUserLocation={true}
                    > 
                    <MapViewDirections
                        origin={source ? {latitude: source[0],longitude: source[0]} : {latitude: 32.162413,longitude: 34.844675}}
                        destination={dest ? {latitude: dest[0],longitude: dest[1]} : {latitude: 32.162413,longitude: 34.844675}}
                        apikey={GOOGLE_MAPS_APIKEY}
                    />
                         {path.map((marker,index) => 
                         {
            
                            console.log("marker")
                            console.log(marker)
            
                         return (
                            <Marker
                            key={index}
                            coordinate={{ latitude : marker[0],longitude : marker[1] }}
                            // title={marker.title}
                            // description={marker.description}
                            />
                        )
                         }
                        )}

                   
                    </MapView>
                </View>
                }
        </>
       
    );
}

function mapStatetoProps(state) {
    return {
      token: state.users.user.login.token
    };
  }
  

  
  export default connect(mapStatetoProps,null)(Map)

const styles = StyleSheet.create({
    container: {
      ...StyleSheet.absoluteFillObject,height: Dimensions.get('window').height,width: Dimensions.get('window').width,justifyContent: 'flex-end',alignItems: 'center',},map: {
      ...StyleSheet.absoluteFillObject,});

错误

ypeError: Cannot read property '0' of undefined

This error is located at:
    in Map (created by ConnectFunction)
    in ConnectFunction (at SceneView.tsx:122)
    in StaticContainer
    in EnsureSingleNavigator (at SceneView.tsx:114)
    in SceneView (at useDescriptors.tsx:153)
    in RCTView (at View.js:34)
    in UnkNown (at CardContainer.tsx:245)
    in RCTView (at View.js:34)
    in UnkNown (at CardContainer.tsx:244)
    in RCTView (at View.js:34)
    in UnkNown (at CardSheet.tsx:33)
    in CardSheet (at Card.tsx:573)
    in RCTView (at View.js:34)
    in UnkNown (at createAnimatedComponent.js:217)
    in AnimatedComponent (at createAnimatedComponent.js:278)
    in AnimatedComponentWrapper (at Card.tsx:555)
    in PanGestureHandler (at GestureHandlerNative.tsx:13)
    in PanGestureHandler (at Card.tsx:549)
    in RCTView (at View.js:34)
    in UnkNown (at createAnimatedComponent.js:217)
    in AnimatedComponent (at createAnimatedComponent.js:278)
    in AnimatedComponentWrapper (at Card.tsx:544)
    in RCTView (at View.js:34)
    in UnkNown (at Card.tsx:538)
    in Card (at CardContainer.tsx:206)
    in CardContainer (at CardStack.tsx:619)
    in RCTView (at View.js:34)
    in UnkNown (at Screens.tsx:84)
    in MaybeScreen (at CardStack.tsx:612)
    in RCTView (at View.js:34)
    in UnkNown (at Screens.tsx:54)
    in MaybeScreenContainer (at CardStack.tsx:494)
    in CardStack (at StackView.tsx:462)
    in KeyboardManager (at StackView.tsx:458)
    in SafeAreaProviderCompat (at StackView.tsx:455)
    in RCTView (at View.js:34)
    in UnkNown (at GestureHandlerRootView.android.js:26)
    in GestureHandlerRootView (at StackView.tsx:454)
    in StackView (at createStackNavigator.tsx:87)
    in StackNavigator (at JoinStack.js:18)
    in JoinStackScreen (at SceneView.tsx:122)
    in StaticContainer
    in EnsureSingleNavigator (at SceneView.tsx:114)
    in SceneView (at useDescriptors.tsx:153)
    in RCTView (at View.js:34)
    in UnkNown (at BottomTabView.tsx:55)
    in SceneContent (at BottomTabView.tsx:172)
    in RCTView (at View.js:34)
    in UnkNown (at ResourceSavingScene.tsx:58)
    in RCTView (at View.js:34)
    in UnkNown (at ResourceSavingScene.tsx:41)
    in ResourceSavingScene (at BottomTabView.tsx:166)
    in RCTView (at View.js:34)
    in UnkNown (at src/index.native.js:123)
    in ScreenContainer (at BottomTabView.tsx:146)
    in RCTView (at View.js:34)
    in UnkNown (at BottomTabView.tsx:145)
    in SafeAreaProviderCompat (at BottomTabView.tsx:144)
    in BottomTabView (at createBottomTabNavigator.tsx:45)
    in BottomTabNavigator (at UserTabNavigator.js:29)
    in MainTabNavigator (created by ConnectFunction)
    in ConnectFunction (at SceneView.tsx:122)
    in StaticContainer
    in EnsureSingleNavigator (at SceneView.tsx:114)
    in SceneView (at useDescriptors.tsx:153)
    in RCTView (at View.js:34)
    in UnkNown (at ResourceSavingScene.tsx:58)
    in RCTView (at View.js:34)
    in UnkNown (at ResourceSavingScene.tsx:41)
    in ResourceSavingScene (at DrawerView.tsx:183)
    in RCTView (at View.js:34)
    in UnkNown (at src/index.native.js:123)
    in ScreenContainer (at DrawerView.tsx:162)
    in RCTView (at View.js:34)
    in UnkNown (at Drawer.tsx:645)
    in RCTView (at View.js:34)
    in UnkNown (at createAnimatedComponent.js:240)
    in AnimatedComponent(View) (at Drawer.tsx:638)
    in RCTView (at View.js:34)
    in UnkNown (at createAnimatedComponent.js:240)
    in AnimatedComponent(View) (at Drawer.tsx:628)
    in PanGestureHandler (at GestureHandlerNative.tsx:13)
    in PanGestureHandler (at Drawer.tsx:619)
    in DrawerView (at DrawerView.tsx:215)
    in SafeAreaProviderCompat (at DrawerView.tsx:213)
    in RCTView (at View.js:34)
    in UnkNown (at GestureHandlerRootView.android.js:26)
    in GestureHandlerRootView (at DrawerView.tsx:212)
    in DrawerView (at createDrawerNavigator.tsx:47)
    in DrawerNavigator (at DrawerNavigator.js:27)
    in MyDrawer (created by ConnectFunction)
    in ConnectFunction (at SceneView.tsx:122)
    in StaticContainer
    in EnsureSingleNavigator (at SceneView.tsx:114)
    in SceneView (at useDescriptors.tsx:153)
    in RCTView (at View.js:34)
    in UnkNown (at CardContainer.tsx:245)
    in RCTView (at View.js:34)
    in UnkNown (at CardContainer.tsx:244)
    in RCTView (at View.js:34)
    in UnkNown (at CardSheet.tsx:33)
    in CardSheet (at Card.tsx:573)
    in RCTView (at View.js:34)
    in UnkNown (at createAnimatedComponent.js:217)
    in AnimatedComponent (at createAnimatedComponent.js:278)
    in AnimatedComponentWrapper (at Card.tsx:555)
    in PanGestureHandler (at GestureHandlerNative.tsx:13)
    in PanGestureHandler (at Card.tsx:549)
    in RCTView (at View.js:34)
    in UnkNown (at createAnimatedComponent.js:217)
    in AnimatedComponent (at createAnimatedComponent.js:278)
    in AnimatedComponentWrapper (at Card.tsx:544)
    in RCTView (at View.js:34)
    in UnkNown (at Card.tsx:538)
    in Card (at CardContainer.tsx:206)
    in CardContainer (at CardStack.tsx:619)
    in RCTView (at View.js:34)
    in UnkNown (at Screens.tsx:84)
    in MaybeScreen (at CardStack.tsx:612)
    in RCTView (at View.js:34)
    in UnkNown (at Screens.tsx:54)
    in MaybeScreenContainer (at CardStack.tsx:494)
    in CardStack (at StackView.tsx:462)
    in KeyboardManager (at StackView.tsx:458)
    in RNCSafeAreaProvider (at SafeAreaContext.tsx:74)
    in SafeAreaProvider (at SafeAreaProviderCompat.tsx:42)
    in SafeAreaProviderCompat (at StackView.tsx:455)
    in GestureHandlerRootView (at GestureHandlerRootView.android.js:31)
    in GestureHandlerRootView (at StackView.tsx:454)
    in StackView (at createStackNavigator.tsx:87)
    in StackNavigator (at routes/index.js:29)
    in AppMainRouter (created by ConnectFunction)
    in ConnectFunction
    in MainNavigation (at App.js:31)
    in EnsureSingleNavigator (at BaseNavigationContainer.tsx:409)
    in BaseNavigationContainer (at NavigationContainer.tsx:91)
    in ThemeProvider (at NavigationContainer.tsx:90)
    in NavigationContainer (at App.js:26)
    in Provider (at App.js:25)
    in App (at renderApplication.js:47)
    in RCTView (at View.js:34)
    in UnkNown (at AppContainer.js:107)
    in RCTView (at View.js:34)
    in UnkNown (at AppContainer.js:134)
    in AppContainer (at renderApplication.js:40)

从模拟器看来,当我尝试访问路径时,错误出现在第 72 行(纬度:路径?路径[0][0]:0)。

如果我删除 Map 并放置一个按钮来打印路径变量,我会得到一个数组,它应该可以像我那样访问。 我构建组件和 API 调用的方式有问题吗?

更新:

我也遇到了 source 和 dest 的问题。 当我将源从数组更改为 2 个独立的双精度数(srcLat 和 srcLng)时,它似乎没有问题。

我唯一能想到的是数组是对内容的引用,因此它可能会产生问题,但条件仍然设置为 false,因此很奇怪。

解决方法

设置加载器的初始状态为真

const [loader,setLoader] = useState(true)

因为 useEffect 的工作方式与您使用的方式一样 componentDidMount,这意味着它最初将呈现组件,然后调用 useEffect

有用的链接:https://medium.com/@felippenardi/how-to-do-componentdidmount-with-react-hooks-553ba39d1571#:~:text=Functions%20passed%20to%20useEffect%20are,executing%20on%20the%20first%20rendering