React Native render error: null is not an object (evaluating origin.location)
React Native render error: null is not an object (evaluating origin.location)
我是 react-native 的新手,决定按照教程尝试克隆一个应用程序。我正在尝试将存储在 redux 中的数据传递到在我的主屏幕上呈现的地图,但是当我 运行 时,我不断收到以下错误:null 不是一个对象(评估 origin.location)。欢迎任何建议、解决方案和快速修复。谢谢
主屏幕代码
import { View, TouchableOpacity, Text } from 'react-native'
import { React } from 'react'
import HeaderTabs from '../components/HeaderTabs'
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete'
import { Ionicons } from '@expo/vector-icons'
import { setDestination, setOrigin } from '../slices/navSlice'
import { useDispatch } from 'react-redux'
import { SafeAreaView } from 'react-native-safe-area-context'
import { GOOGLE_MAPS_APIKEY } from '@env'
import Map from './components/Map'
const Home = ({navigation}) =>{
const dispatch = useDispatch();
return (
<SafeAreaView style={{ backgroundColor:"white",
flex:1,
padding:5,
marginTop:-20
}}>
<View style={{alignItems:"flex-end"}} >
<TouchableOpacity onPress={() => {navigation.navigate("CustomerInfo")}}>
<Ionicons name="person-circle" size={30} color="black" />
</TouchableOpacity>
</View>
<HeaderTabs />
<View style={{marginTop:15, flexDirection:"row"}}>
<GooglePlacesAutocomplete
query={{key: GOOGLE_MAPS_APIKEY}}
enablePoweredByContainer={false}
onPress={(data, details = null) => {
dispatch(setOrigin({
location: details.geometry.location,
description: data.description,
})
);
dispatch(setDestination(null));
}}
fetchDetails={true}
returnKeyType={"search"}
placeholder='Enter package pickup location'
debounce={400}
nearbyPlacesAPI='GooglePlacesSearch'
styles={{
textInput:{
backgroundColor:"#eee",
borderRadius:15,
fontFamily:"Poppins_500Medium",
marginTop:10,
fontSize:18,
},
textInputContainer:{
backgroundColor:"#eee",
borderRadius:15,
flexDirection:"row",
alignItems:"center",
width:380
},
}}
renderLeftButton={() => (
<View style={{
marginLeft:10
}}>
<Ionicons name="location" size={20} color="green" />
</View>
)}
renderRightButton={() => (
<View style={{
flexDirection:"row",
marginRight:5,
backgroundColor:"white",
padding:9,
borderRadius:30,
alignItems:"center"
}}>
<Ionicons name="search" size={15} color="black" />
</View>
)}
/>
</View>
<Map />
</SafeAreaView>
)};
export default Home;
地图组件代码
import { View, Text } from 'react-native'
import React from 'react'
import MapView, { Marker } from 'react-native-maps'
import { useSelector } from 'react-redux'
import { selectOrigin } from '../slices/navSlice'
const Map = () => {
const origin = useSelector(selectOrigin);
return (
<MapView
style={{flex:1, marginTop:10}}
initialRegion={{
latitude: origin.location.lat,
longitude: origin.location.lng,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
);
};
export default Map;
origin.location 来自哪里
const initialState = {
origin: null,
destination: null,
travelTimeInformation: null
}
export const navSlice = createSlice({
name: "nav",
initialState,
reducer: {
setOrigin: (state, action) => {
state.origin = action.payload;
},
setDestination: (state, action) => {
state.destination = action.payload;
},
setTravelTimeInformation: (state, action) => {
state.travelTimeInformation = action.payload;
},
},
});
export const { setOrigin, setDestination, setTravelTimeInformation } = navSlice.actions;
export const selectOrigin = (state) => state.nav.origin;
export const selectDestination = (state) => state.nav.destination;
export const selectTravelTimeInformation = (state) => state.nav.travelTimeInformation;
export default navSlice.reducer;
问题
origin
状态值初始为null
。
const initialState = {
origin: null, // <-- initially null here
destination: null,
travelTimeInformation: null
}
并且代码正在尝试访问此空值。
const Map = () => {
const origin = useSelector(selectOrigin);
return (
<MapView
style={{flex:1, marginTop:10}}
initialRegion={{
latitude: origin.location.lat,
longitude: origin.location.lng,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
);
};
解决方案
你有几个选择。这里有4个,可能还有其他的。
有条件地在正在填充的 origin
状态上呈现 MapView
组件。
const Map = () => {
const origin = useSelector(selectOrigin);
return origin?.location
? (
<MapView
style={{flex:1, marginTop:10}}
initialRegion={{
latitude: origin.location.lat,
longitude: origin.location.lng,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
) : null;
};
在 origin
访问上使用可选链接运算符并提供回退值。
const Map = () => {
const origin = useSelector(selectOrigin);
return (
<MapView
style={{flex:1, marginTop:10}}
initialRegion={{
latitude: origin?.location?.lat ?? 0, // use fallback value that makes sense
longitude: origin?.location?.lng ?? 0, // use fallback value that makes sense
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
);
};
从选择器中提供一个有效的、已定义的原始值。
const defaultOrigin = { location: { lat: 0, lng: 0 } }; // use origin value that makes sense
export const selectOrigin = (state) => state.nav.origin ?? defaultOrigin;
或者只是提供一个更有用的初始状态值。
const defaultOrigin = { location: { lat: 0, lng: 0 } }; // use origin value that makes sense
const initialState = {
origin: defaultOrigin,
destination: null,
travelTimeInformation: null
}
我是 react-native 的新手,决定按照教程尝试克隆一个应用程序。我正在尝试将存储在 redux 中的数据传递到在我的主屏幕上呈现的地图,但是当我 运行 时,我不断收到以下错误:null 不是一个对象(评估 origin.location)。欢迎任何建议、解决方案和快速修复。谢谢
主屏幕代码
import { View, TouchableOpacity, Text } from 'react-native'
import { React } from 'react'
import HeaderTabs from '../components/HeaderTabs'
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete'
import { Ionicons } from '@expo/vector-icons'
import { setDestination, setOrigin } from '../slices/navSlice'
import { useDispatch } from 'react-redux'
import { SafeAreaView } from 'react-native-safe-area-context'
import { GOOGLE_MAPS_APIKEY } from '@env'
import Map from './components/Map'
const Home = ({navigation}) =>{
const dispatch = useDispatch();
return (
<SafeAreaView style={{ backgroundColor:"white",
flex:1,
padding:5,
marginTop:-20
}}>
<View style={{alignItems:"flex-end"}} >
<TouchableOpacity onPress={() => {navigation.navigate("CustomerInfo")}}>
<Ionicons name="person-circle" size={30} color="black" />
</TouchableOpacity>
</View>
<HeaderTabs />
<View style={{marginTop:15, flexDirection:"row"}}>
<GooglePlacesAutocomplete
query={{key: GOOGLE_MAPS_APIKEY}}
enablePoweredByContainer={false}
onPress={(data, details = null) => {
dispatch(setOrigin({
location: details.geometry.location,
description: data.description,
})
);
dispatch(setDestination(null));
}}
fetchDetails={true}
returnKeyType={"search"}
placeholder='Enter package pickup location'
debounce={400}
nearbyPlacesAPI='GooglePlacesSearch'
styles={{
textInput:{
backgroundColor:"#eee",
borderRadius:15,
fontFamily:"Poppins_500Medium",
marginTop:10,
fontSize:18,
},
textInputContainer:{
backgroundColor:"#eee",
borderRadius:15,
flexDirection:"row",
alignItems:"center",
width:380
},
}}
renderLeftButton={() => (
<View style={{
marginLeft:10
}}>
<Ionicons name="location" size={20} color="green" />
</View>
)}
renderRightButton={() => (
<View style={{
flexDirection:"row",
marginRight:5,
backgroundColor:"white",
padding:9,
borderRadius:30,
alignItems:"center"
}}>
<Ionicons name="search" size={15} color="black" />
</View>
)}
/>
</View>
<Map />
</SafeAreaView>
)};
export default Home;
地图组件代码
import { View, Text } from 'react-native'
import React from 'react'
import MapView, { Marker } from 'react-native-maps'
import { useSelector } from 'react-redux'
import { selectOrigin } from '../slices/navSlice'
const Map = () => {
const origin = useSelector(selectOrigin);
return (
<MapView
style={{flex:1, marginTop:10}}
initialRegion={{
latitude: origin.location.lat,
longitude: origin.location.lng,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
);
};
export default Map;
origin.location 来自哪里
const initialState = {
origin: null,
destination: null,
travelTimeInformation: null
}
export const navSlice = createSlice({
name: "nav",
initialState,
reducer: {
setOrigin: (state, action) => {
state.origin = action.payload;
},
setDestination: (state, action) => {
state.destination = action.payload;
},
setTravelTimeInformation: (state, action) => {
state.travelTimeInformation = action.payload;
},
},
});
export const { setOrigin, setDestination, setTravelTimeInformation } = navSlice.actions;
export const selectOrigin = (state) => state.nav.origin;
export const selectDestination = (state) => state.nav.destination;
export const selectTravelTimeInformation = (state) => state.nav.travelTimeInformation;
export default navSlice.reducer;
问题
origin
状态值初始为null
。
const initialState = {
origin: null, // <-- initially null here
destination: null,
travelTimeInformation: null
}
并且代码正在尝试访问此空值。
const Map = () => {
const origin = useSelector(selectOrigin);
return (
<MapView
style={{flex:1, marginTop:10}}
initialRegion={{
latitude: origin.location.lat,
longitude: origin.location.lng,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
);
};
解决方案
你有几个选择。这里有4个,可能还有其他的。
有条件地在正在填充的
origin
状态上呈现MapView
组件。const Map = () => { const origin = useSelector(selectOrigin); return origin?.location ? ( <MapView style={{flex:1, marginTop:10}} initialRegion={{ latitude: origin.location.lat, longitude: origin.location.lng, latitudeDelta: 0.0922, longitudeDelta: 0.0421, }} /> ) : null; };
在
origin
访问上使用可选链接运算符并提供回退值。const Map = () => { const origin = useSelector(selectOrigin); return ( <MapView style={{flex:1, marginTop:10}} initialRegion={{ latitude: origin?.location?.lat ?? 0, // use fallback value that makes sense longitude: origin?.location?.lng ?? 0, // use fallback value that makes sense latitudeDelta: 0.0922, longitudeDelta: 0.0421, }} /> ); };
从选择器中提供一个有效的、已定义的原始值。
const defaultOrigin = { location: { lat: 0, lng: 0 } }; // use origin value that makes sense export const selectOrigin = (state) => state.nav.origin ?? defaultOrigin;
或者只是提供一个更有用的初始状态值。
const defaultOrigin = { location: { lat: 0, lng: 0 } }; // use origin value that makes sense const initialState = { origin: defaultOrigin, destination: null, travelTimeInformation: null }