React Native:将 class 个组件转换为功能组件
React Native: Convert class components into functional components
幸运的是,我通过 https://mdmoin07.medium.com/react-native-google-maps-with-autocomplete-45a5617be2f5 找到了一个关于 React Native Google Maps with Autocomplete 的解决方案。我能够使用功能组件转换代码。最初,我的代码似乎可以从 react-native-google-maps-autocomplete 获取地址,但不幸的是,地图没有显示并给出错误。
错误警告:道具类型失败:道具 region.latitude
在 MapView
中被标记为必需,但其值为 undefined
。
import React, { useEffect, useRef, useState } from 'react';
import { View, StyleSheet } from 'react-native';
//mport RNMapView, { Circle, Marker, Polyline } from 'react-native-maps';
import { getLocation, geocodeLocationByName } from '../services/location-service';
//import MapInput from '../services/MapInput';
import MyMapView from '../components/map/MapView';
import MapInput from '../components/map/MapInput';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import MapView, { Marker } from 'react-native-maps';
function MapContainer({ coords }) {
/*
state = {
region: {}
};
*/
const [region, setState] = useState({});
useEffect(() => {
getInitialState();
}, []);
function getInitialState() {
getLocation().then(
(data) => {
console.log(data);
setState({
region: {
latitude: data.latitude,
longitude: data.longitude,
latitudeDelta: 0.003,
longitudeDelta: 0.003
}
});
}
);
}
function getCoordsFromName(loc) {
setState(region);
}
function onMapRegionChange(region) {
this.setState({ region });
}
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={true}
returnKeyType={'search'} // Can be left out for default return key
listViewDisplayed={false} // true/false/undefined
fetchDetails={true}
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
getCoordsFromName(details.geometry.location);
console.log(data);
}
}
query={{
key: "API KEY",
language: 'en',
components: "country:ph",
}}
nearbyPlacesAPI='GooglePlacesSearch'
debounce={300}
/>
</View>
{
region['latitude'] ?
<View style={{ flex: 1 }}>
<MapView
style={{ flex: 1 }}
ref={mapRef}
region={region.latitude}
showsUserLocation={true}
onRegionChange={(reg) => onMapRegionChange(reg)} >
<Marker
coordinate={region.latitude} />
</MapView>
</View>
: null}
</View>
);
}
export default MapContainer;
这些代码是 class 个来自我找到的参考的组件。
import React, { useEffect, useRef, useState} from 'react';
import { View, StyleSheet } from 'react-native';
//mport RNMapView, { Circle, Marker, Polyline } from 'react-native-maps';
import { getLocation, geocodeLocationByName } from '../services/location-service';
//import MapInput from '../services/MapInput';
import MyMapView from '../components/map/MapView';
import MapInput from '../components/map/MapInput';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import MapView, {Marker} from 'react-native-maps';
class MapContainer extends React.Component {
state = {
region: {}
};
componentDidMount() {
this.getInitialState();
}
getInitialState() {
getLocation().then(
(data) => {
console.log(data);
this.setState({
region: {
latitude: data.latitude,
longitude: data.longitude,
latitudeDelta: 0.003,
longitudeDelta: 0.003
}
});
}
);
}
getCoordsFromName(loc) {
this.setState({
region: {
latitude: loc.lat,
longitude: loc.lng,
latitudeDelta: 0.003,
longitudeDelta: 0.003
}
});
}
onMapRegionChange(region) {
this.setState({ region });
}
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={true}
returnKeyType={'search'} // Can be left out for default return key
listViewDisplayed={false} // true/false/undefined
fetchDetails={true}
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
this.getCoordsFromName(details.geometry.location);
console.log(data);
}
}
query={{
key: "API KEY",
language: 'en',
components: "country:ph",
}}
nearbyPlacesAPI='GooglePlacesSearch'
debounce={300}
/>
</View>
{
this.state.region['latitude'] ?
<View style={{ flex: 1 }}>
<MapView
style={{ flex: 1 }}
region={this.state.region}
showsUserLocation={true}
onRegionChange={(reg) => this.onMapRegionChange(reg)} >
<Marker
coordinate={this.state.region} />
</MapView>
</View>
: null}
</View>
);
}
}
export default MapContainer;
感谢您热心回答我的问题。我来自菲律宾。 Maraming Salamat po.
请尝试 initialRegion
而不是 MapView 组件中的区域,我还会定义一个具有纬度、经度和相应增量的整个区域对象。
我已经解决了将其 class 转换为功能组件的问题。请检查代码并尝试重新 运行 它。
import React, { useEffect, useRef, useState } from "react";
import { View, StyleSheet } from "react-native";
//mport RNMapView, { Circle, Marker, Polyline } from 'react-native-maps';
import {
getLocation,
geocodeLocationByName,
} from "../services/location-service";
//import MapInput from '../services/MapInput';
import MyMapView from "../components/map/MapView";
import MapInput from "../components/map/MapInput";
import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
import MapView, { Marker } from "react-native-maps";
function MapContainer({ coords }) {
const [region, setRegion] = useState({
latitude: '',
longitude: '',
latitudeDelta: 0.003,
longitudeDelta: 0.003,
});
useEffect(() => {
getInitialState();
}, []);
function getInitialState() {
getLocation().then((data) => {
console.log(data);
setRegion({
latitude: data.latitude,
longitude: data.longitude,
latitudeDelta: 0.003,
longitudeDelta: 0.003,
});
});
}
function getCoordsFromName(loc) {
setRegion({
latitude: loc.latitude,
longitude: loc.longitude,
latitudeDelta: 0.003,
longitudeDelta: 0.003,
});
}
function onMapRegionChange(getRegion ) {
setRegion(getRegion);
}
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<GooglePlacesAutocomplete
placeholder="Search"
minLength={2} // minimum length of text to search
autoFocus={true}
returnKeyType={"search"} // Can be left out for default return key
listViewDisplayed={false} // true/false/undefined
fetchDetails={true}
onPress={(data, details = null) => {
// 'details' is provided when fetchDetails = true
getCoordsFromName(details.geometry.location);
console.log(data);
}}
query={{
key: "API KEY",
language: "en",
components: "country:ph",
}}
nearbyPlacesAPI="GooglePlacesSearch"
debounce={300}
/>
</View>
{ region ? (
<View style={{ flex: 1 }}>
<MapView
style={{ flex: 1 }}
ref={mapRef}
region={region}
showsUserLocation={true}
onRegionChange={(reg) => onMapRegionChange(reg)}
>
<Marker coordinate={{ latitude : region.latitude , longitude : region.longitude }}/>
</MapView>
</View>
) : null}
</View>
);
}
export default MapContainer;
编辑答案
对于 Google 的地方自动完成你变得不确定,因为你没有从响应的正确值中保存它。
像下面这样保存:(还要检查 console.log 数据和详细信息)
onPress={(data, details = null) => {
setRegion({
latitude: details.geometry.location.lat,
longitude: details.geometry.location.lng,
latitudeDelta: 0.003,
longitudeDelta: 0.003,
});
}}
对于地图问题,您可以在 useState 中为纬度和经度提供任何默认值
const [region, setRegion] = useState({
latitude: 22.5726,
longitude: 88.3639,
latitudeDelta: 1,
longitudeDelta: 1,
});
根据给定的代码,我只能大致了解您的问题,如果您在此之后也遇到问题,请提供完整的代码。
幸运的是,我通过 https://mdmoin07.medium.com/react-native-google-maps-with-autocomplete-45a5617be2f5 找到了一个关于 React Native Google Maps with Autocomplete 的解决方案。我能够使用功能组件转换代码。最初,我的代码似乎可以从 react-native-google-maps-autocomplete 获取地址,但不幸的是,地图没有显示并给出错误。
错误警告:道具类型失败:道具 region.latitude
在 MapView
中被标记为必需,但其值为 undefined
。
import React, { useEffect, useRef, useState } from 'react';
import { View, StyleSheet } from 'react-native';
//mport RNMapView, { Circle, Marker, Polyline } from 'react-native-maps';
import { getLocation, geocodeLocationByName } from '../services/location-service';
//import MapInput from '../services/MapInput';
import MyMapView from '../components/map/MapView';
import MapInput from '../components/map/MapInput';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import MapView, { Marker } from 'react-native-maps';
function MapContainer({ coords }) {
/*
state = {
region: {}
};
*/
const [region, setState] = useState({});
useEffect(() => {
getInitialState();
}, []);
function getInitialState() {
getLocation().then(
(data) => {
console.log(data);
setState({
region: {
latitude: data.latitude,
longitude: data.longitude,
latitudeDelta: 0.003,
longitudeDelta: 0.003
}
});
}
);
}
function getCoordsFromName(loc) {
setState(region);
}
function onMapRegionChange(region) {
this.setState({ region });
}
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={true}
returnKeyType={'search'} // Can be left out for default return key
listViewDisplayed={false} // true/false/undefined
fetchDetails={true}
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
getCoordsFromName(details.geometry.location);
console.log(data);
}
}
query={{
key: "API KEY",
language: 'en',
components: "country:ph",
}}
nearbyPlacesAPI='GooglePlacesSearch'
debounce={300}
/>
</View>
{
region['latitude'] ?
<View style={{ flex: 1 }}>
<MapView
style={{ flex: 1 }}
ref={mapRef}
region={region.latitude}
showsUserLocation={true}
onRegionChange={(reg) => onMapRegionChange(reg)} >
<Marker
coordinate={region.latitude} />
</MapView>
</View>
: null}
</View>
);
}
export default MapContainer;
这些代码是 class 个来自我找到的参考的组件。
import React, { useEffect, useRef, useState} from 'react';
import { View, StyleSheet } from 'react-native';
//mport RNMapView, { Circle, Marker, Polyline } from 'react-native-maps';
import { getLocation, geocodeLocationByName } from '../services/location-service';
//import MapInput from '../services/MapInput';
import MyMapView from '../components/map/MapView';
import MapInput from '../components/map/MapInput';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import MapView, {Marker} from 'react-native-maps';
class MapContainer extends React.Component {
state = {
region: {}
};
componentDidMount() {
this.getInitialState();
}
getInitialState() {
getLocation().then(
(data) => {
console.log(data);
this.setState({
region: {
latitude: data.latitude,
longitude: data.longitude,
latitudeDelta: 0.003,
longitudeDelta: 0.003
}
});
}
);
}
getCoordsFromName(loc) {
this.setState({
region: {
latitude: loc.lat,
longitude: loc.lng,
latitudeDelta: 0.003,
longitudeDelta: 0.003
}
});
}
onMapRegionChange(region) {
this.setState({ region });
}
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={true}
returnKeyType={'search'} // Can be left out for default return key
listViewDisplayed={false} // true/false/undefined
fetchDetails={true}
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
this.getCoordsFromName(details.geometry.location);
console.log(data);
}
}
query={{
key: "API KEY",
language: 'en',
components: "country:ph",
}}
nearbyPlacesAPI='GooglePlacesSearch'
debounce={300}
/>
</View>
{
this.state.region['latitude'] ?
<View style={{ flex: 1 }}>
<MapView
style={{ flex: 1 }}
region={this.state.region}
showsUserLocation={true}
onRegionChange={(reg) => this.onMapRegionChange(reg)} >
<Marker
coordinate={this.state.region} />
</MapView>
</View>
: null}
</View>
);
}
}
export default MapContainer;
感谢您热心回答我的问题。我来自菲律宾。 Maraming Salamat po.
请尝试 initialRegion
而不是 MapView 组件中的区域,我还会定义一个具有纬度、经度和相应增量的整个区域对象。
我已经解决了将其 class 转换为功能组件的问题。请检查代码并尝试重新 运行 它。
import React, { useEffect, useRef, useState } from "react";
import { View, StyleSheet } from "react-native";
//mport RNMapView, { Circle, Marker, Polyline } from 'react-native-maps';
import {
getLocation,
geocodeLocationByName,
} from "../services/location-service";
//import MapInput from '../services/MapInput';
import MyMapView from "../components/map/MapView";
import MapInput from "../components/map/MapInput";
import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
import MapView, { Marker } from "react-native-maps";
function MapContainer({ coords }) {
const [region, setRegion] = useState({
latitude: '',
longitude: '',
latitudeDelta: 0.003,
longitudeDelta: 0.003,
});
useEffect(() => {
getInitialState();
}, []);
function getInitialState() {
getLocation().then((data) => {
console.log(data);
setRegion({
latitude: data.latitude,
longitude: data.longitude,
latitudeDelta: 0.003,
longitudeDelta: 0.003,
});
});
}
function getCoordsFromName(loc) {
setRegion({
latitude: loc.latitude,
longitude: loc.longitude,
latitudeDelta: 0.003,
longitudeDelta: 0.003,
});
}
function onMapRegionChange(getRegion ) {
setRegion(getRegion);
}
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<GooglePlacesAutocomplete
placeholder="Search"
minLength={2} // minimum length of text to search
autoFocus={true}
returnKeyType={"search"} // Can be left out for default return key
listViewDisplayed={false} // true/false/undefined
fetchDetails={true}
onPress={(data, details = null) => {
// 'details' is provided when fetchDetails = true
getCoordsFromName(details.geometry.location);
console.log(data);
}}
query={{
key: "API KEY",
language: "en",
components: "country:ph",
}}
nearbyPlacesAPI="GooglePlacesSearch"
debounce={300}
/>
</View>
{ region ? (
<View style={{ flex: 1 }}>
<MapView
style={{ flex: 1 }}
ref={mapRef}
region={region}
showsUserLocation={true}
onRegionChange={(reg) => onMapRegionChange(reg)}
>
<Marker coordinate={{ latitude : region.latitude , longitude : region.longitude }}/>
</MapView>
</View>
) : null}
</View>
);
}
export default MapContainer;
编辑答案
对于 Google 的地方自动完成你变得不确定,因为你没有从响应的正确值中保存它。 像下面这样保存:(还要检查 console.log 数据和详细信息)
onPress={(data, details = null) => {
setRegion({
latitude: details.geometry.location.lat,
longitude: details.geometry.location.lng,
latitudeDelta: 0.003,
longitudeDelta: 0.003,
});
}}
对于地图问题,您可以在 useState 中为纬度和经度提供任何默认值
const [region, setRegion] = useState({
latitude: 22.5726,
longitude: 88.3639,
latitudeDelta: 1,
longitudeDelta: 1,
});
根据给定的代码,我只能大致了解您的问题,如果您在此之后也遇到问题,请提供完整的代码。