谷歌为访问其地图服务提供了大量的API,其中之一就是地点API。Places API主要通过HTTP请求为你提供有关地方的信息。你可以获得所有你需要的关于当地地址、城镇、城市、区、餐馆或任何其他地方的信息,包括其坐标。
地方API包括大量的功能,如返回与搜索字符串相关的地方列表,提供一个地方的照片,以及许多其他功能。其最常用的功能之一是自动完成服务。
使用自动完成服务,谷歌可以通过API自动填写被搜索的地方的地址或名称。因此,例如,当你的用户输入他们想要订购的餐厅名称时,你可以根据他们输入的内容向他们提供建议。
在这篇文章中,我们将看看如何在React Native中使用自动完成服务。然而,我们不需要直接使用Places API,因为一个叫做 [react-native-google-places-autocomplete](https://www.npmjs.com/package/react-native-google-places-autocomplete)的React Native包可以为我们处理这个问题。
因此,让我们看看我们如何在React Native项目中使用react-native-google-places-autocomplete 包,以及它的一些关键功能和我们如何定制它以适应我们的项目。
设置Google Places API
react-native-google-places-autocomplete 包只是一个访问Places API的媒介。如果不首先设置一个Google Cloud项目来使用Places API,它就不会发挥作用。因此,让我告诉你如何在四个步骤中做到这一点:
- 创建一个项目
- 启用计费
- 启用所需的API
- 创建一个API密钥
让我们从创建一个谷歌云项目开始。
创建一个谷歌云项目
没有谷歌云项目,我们就不能使用任何谷歌API服务。如果你还没有注册,请到谷歌云控制台去注册:

你会进入上图所示的页面。如果你以前没有创建过项目,点击 "创建或选择项目 "按钮。一个模式将立即弹出。点击右上方的 "新项目"。
一个新的页面将加载,要求你输入项目的名称和位置--"位置 "是指该项目应属于哪个组织。你可以把位置设为 "无组织",只需为你的项目输入一个名称。
最后,点击 "创建 "来创建项目。然后,你可以选择项目或访问项目页面,查看你的项目列表。
启用Google Places API的计费功能
Google Places API不是永远免费的。谷歌采用的是随用随付的定价模式。但是你的前几个请求每个月都是免费的。
谷歌强制要求你在使用Places API之前为你的项目启用计费。
前往计费页面,并选择你想启用计费的项目。将会弹出一个模式,如果你还没有,只需点击 "创建计费账户"。
按照谷歌的官方指南来创建一个计费账户。
启用所需的API
你只需要启用Places API和Geocoding API来使用react-native-google-places-autocomplete 。让我们接下来做这个。
前往你的项目仪表板,它应该看起来像这样:

如果它不像上面的图片,确保侧边栏的 "启用API和服务 "被选中。接下来点击导航栏上的 "启用API和服务"。它将带你到API库页面。

搜索 "Places API "并点击结果。下一页包含关于Places API的信息,包括价格信息和一个为你的项目启用API的按钮。点击 "启用 "按钮,这就可以了。
如果你还没有为你的项目启用计费,当你试图启用Places API时,你会被提示这样做。
之后,回到API库页面,也启用地理编码API。
创建一个API密钥
这是我们在使用该包之前必须做的最后一步。转到你的API仪表板。在左边的侧栏,选择 "证书 "选项。

点击顶部导航栏的 "创建证书",选择 "API密钥",这将为你的项目创建一个API密钥。有了这个API密钥,你只能访问你所启用的API。复制API密钥并将其保存在安全的地方。
你可能会注意到在你的API密钥旁边有一个警告图标。重要的是你要注意它。谷歌建议你将你的API密钥只限制在你的应用程序中。否则,如果你不能保持你的API密钥的秘密,API密钥将对任何其他应用程序或网站无用。
这对于生产目的来说主要是有用的。由于我们只是要测试react-native-google-places-autocomplete 包的功能,所以没有必要限制密钥。
使用react-native-google-places-autocomplete
这个 [react-native-google-places-autocomplete](https://www.npmjs.com/package/react-native-google-places-autocomplete)npm包提供了一个可定制的组件来使用Google Places的自动完成服务。
它还使用了Places Details服务来提供关于搜索到的地方的更多细节,包括用户评论和坐标,以及Geocoding API来将可读地址转换为几何坐标,反之亦然。
要跟上这篇文章并看到这个包在工作,请设置一个React Native项目。
设置一个React Native项目
对于我们的React Native项目的例子,我们将为美食家创建一个应用程序来查找吃饭的地方。我们不会去看构建应用程序的每一步,因为本文的主要重点是展示一些如何使用react-native-google-places-autocomplete 包的例子。
到你的终端,运行以下程序:
npx react-native init Foodies
如果你在创建React Native项目时遇到了 [TypeError: cli.init is not a function](https://stackoverflow.com/questions/72768245/typeerror-cli-init-is-not-a-function-for-react-native)问题,卸载全局的react-native-cli 和react-native 。现在只重新安装全局的react-native 。
现在我们来安装依赖项。我们现在只需要一个依赖项:react-native-google-places-autocomplete 包:
npm install react-native-google-places-autocomplete
该包提供了一个组件,包含了我们在应用中使用和定制Places API所需的一切。让我们看看一个基本的例子:
import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete';
import {apiKey} from './config'; // your google cloud api key
const App = () => {
return (
<SafeAreaView>
<GooglePlacesAutocomplete
placeholder="Type a place"
query={{key: apiKey}}
/>
</SafeAreaView>
);
};
让我们来看看上面的例子的一些重要部分。
GooglePlacesAutocomplete 是文本输入表格,用户在其中输入一个地方的名称。当用户输入时,根据用户输入的内容建议的地方的模版将以下拉方式出现。
查询道具是唯一需要的道具;如果没有它的关键属性,自动完成包将无法使用地点API。你需要导入你的API密钥,并在这里使用它。另外,不要忘记在你的云项目上启用计费,以使用Places和Geocoding APIs。
在你的React Native项目中存储敏感信息并不是一个安全的做法。让我们讨论一下如何保护您的API密钥。
确保你的API密钥的安全
不要在React Native项目中存储你的API密钥,这一点非常重要。任何拥有你的应用包的人都可以访问你的API密钥,所以这不是一个安全的存储方法。
你可以通过使用一个服务器来存储你的API密钥来解决这个问题。这样,当用户打开应用程序时,你只需向你的服务器发出请求,获取API密钥。
也有一些措施可以保证服务器中的API密钥的安全。Brad Traversy关于保护API密钥的视频演示了如何做到这一点。
处理来自Google Places API的响应
来自Google Places API的第一组响应是自动完成的建议。react-native-google-places-autocomplete 包处理这组响应,所以我们不必担心它们。
然而,还有其他响应将由用户事件触发。例如,当建议的地址被按下时,用户的输入不会再返回任何建议(即未找到的地方)。这些响应将必须由我们来处理。
同样,自动完成包已经为我们完成了困难的部分,提供了处理这些响应的事件道具。让我们来看看一个例子:
const App = () => {
return (
<SafeAreaView>
<GooglePlacesAutocomplete
placeholder="Type a place"
query={{key: apiKey}}
fetchDetails={true}
onPress={(data, details = null) => console.log(data, details)}
onFail={error => console.log(error)}
onNotFound={() => console.log('no results')}
/>
</SafeAreaView>
);
};
引入的这些新道具--onPress,onFail, 和onNotFound --是至关重要的。当使用像这样的Places API的包时,你可以使用这些道具来回答这样的问题:
- 当用户点选一个建议时会发生什么?
- 当搜索字符串没有结果时会发生什么?
- 当从API中获取数据失败时会发生什么?
自动完成包提供了用props来回答这些问题的方法。我们要做的是用自定义函数来处理响应。好吧,让我们一个接一个地解决这些问题。
当用户点选一个建议时会发生什么?
当用户点选一个建议时,所选地点的信息将作为参数传入函数,然后传入onPress 道具。上面的例子中的两个参数--data 和details --都构成了关于这个地方的信息。
data 参数返回一个关于该地基本信息的对象,如描述或地址名称、国家、城市和其他细节。
如果fetchDetails 道具是false ,details 参数将返回与数据对象相同的对象。
fetchDetails 道具默认设置为false ,但当设置为true ,details 参数会给出关于该地的更多详细信息,包括几何图形。谷歌在他们的文档中提供了一个完整的地点详细信息响应的例子。
当一个搜索字符串没有结果时,会发生什么?
很有可能,用户有时会输入一个搜索字符串,但没有收到任何结果。通过onNotFound ,我们可以在整个项目中创建没有结果的意识。然后,在你的应用程序中,你可以处理它应该如何显示,或者根据这个反应应该或不应该发生什么。
例如,我们可以停用所有其他功能(比如进入下一步订购食品),并显示一个表明没有结果的自定义消息。
另外,如果你只想提醒用户,而不对你应用中其他地方没有结果做任何特殊处理,你可以使用 [FlatList listEmptyComponent](https://reactnative.dev/docs/flatlist#listemptycomponent)道具来提醒用户没有找到结果。
你可以通过传入一个组件或一个元素来做到这一点,像这样:
const App = () => {
return (
<SafeAreaView>
<GooglePlacesAutocomplete
placeholder="Type a place"
onPress={(data, details = null) => console.log(data, details)}
query={{key: apiKey}}
fetchDetails={true}
onFail={error => console.log(error)}
onNotFound={() => console.log('no results')}
listEmptyComponent={() => (
<View style={{flex: 1}}>
<Text>No results were found</Text>
</View>
)}
/>
</SafeAreaView>
);
};
作为上述代码的结果,如果用户输入的东西没有结果,文本 "没有找到结果 "将显示在搜索栏下:

当从API中获取数据失败时会发生什么?
从Places API中获取数据有时也很可能导致错误。例如,Places API可能会抛出自己的错误,因为你的谷歌云项目或计费地址存在配置问题。
当API出现错误时,onFail prop会返回一个错误,无论是在使用Places API还是Geocoding API时。
你在这里可能遇到的一个非常常见的问题是,当你的项目没有启用计费或其他一些必要的计费的问题。
用预定义的地方进行搜索
你可以使用你的用户最喜欢或最常去的地方作为GooglePlacesAutocomplete 组件的预定义地方。
一个预定义的地方包含一个带有该地方信息的地址。你可以选择向用户显示地址或任何你想要的名称。
如果你使用预定义的地方,当用户关注文本输入来搜索地址时,预定义的选项将作为自动完成的建议弹出。
下面是如何将两个地点--Dominos Pizza 和Chicken Republic --设置为favorite 类型的预定义场所:
const App = () => {
return (
<SafeAreaView>
<GooglePlacesAutocomplete
placeholder="Type a place"
onPress={(data, details = null) => console.log(data, details)}
query={{key: apiKey}}
fetchDetails={true}
onFail={error => console.log(error)}
onNotFound={() => console.log('no results')}
predefinedPlaces={[
{
type: 'favorite',
description: 'Dominos Pizza',
geometry: {location: {lat: 48.8152937, lng: 2.4597668}},
},
{
type: 'favorite',
description: 'Chicken Republic',
geometry: {location: {lat: 48.8496818, lng: 2.2940881}},
},
]}
/>
</SafeAreaView>
);
};
在上面的代码中,描述是将显示给用户的名称。当任何预定义选项被选中时,你为该地点创建的对象将被返回,并带有该地点的data 和details 参数。
这个对象并不限于只有类型、描述和几何形状。你可以添加更多关于这个地方的信息。
作为上述代码的结果,你应该看到这些favorite 预定义的地方,甚至在用户开始输入之前就出现了建议。请看下面的结果:

使用一个自定义的文本输入组件
默认情况下,react-native-google-places-autocomplete 包使用React Native 的 [TextInput](https://blog.logrocket.com/complete-guide-textinput-react-native/)组件来输入文本。然而,你并不拘泥于包的选择
有了textInputProps 这个道具,你可以使用任何你选择的自定义组件,比如React Native Elements的Input :
import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete';
import {apiKey} from './config'; // your google cloud api key
import {Input} from '@rneui/themed';
const App = () => {
return (
<SafeAreaView>
<GooglePlacesAutocomplete
placeholder="Type a place"
onPress={(data, details = null) => console.log(data, details)}
query={{key: apiKey}}
fetchDetails={true}
onFail={error => console.log(error)}
onNotFound={() => console.log('no results')}
textInputProps={{
InputComp: Input,
}}
/>
</SafeAreaView>
);
};
textInputProps 是文本输入组件的所有道具的一个对象。因此,如果你使用React Native的 ,你可以在这里使用它的特定道具。比如说。TextInput:
const App = () => {
return (
<SafeAreaView>
<GooglePlacesAutocomplete
placeholder="Type a place"
onPress={(data, details = null) => console.log(data, details)}
query={{key: apiKey}}
fetchDetails={true}
onFail={error => console.log(error)}
onNotFound={() => console.log('no results')}
textInputProps={{
autoFocus: true,
blurOnSubmit: false,
}}
/>
</SafeAreaView>
);
};;
上面textInputProps中使用的道具都是特定于React Native 的 [TextInput](https://blog.logrocket.com/complete-guide-textinput-react-native/).当你使用第三方库时,也会发生同样的事情。
为你的GooglePlacesAutocomplete 组件设置样式
GooglePlacesAutocomplete 组件的默认样式是很有风格的,所以它们可能对你的应用程序来说已经足够了。
然而,你可以在默认的样式上添加一些东西,使之适合你的应用程序。你也可以完全去掉默认的样式,从头开始完全定制样式。
GooglePlacesAutocomplete 组件有一个样式道具,用于为所有组件设置样式,从文本输入到下拉菜单。让我们看看它的作用:
const App = () => {
return (
<SafeAreaView>
<GooglePlacesAutocomplete
placeholder="Type a place"
onPress={(data, details = null) => console.log(data, details)}
query={{key: apiKey}}
fetchDetails={true}
onFail={error => console.log(error)}
onNotFound={() => console.log('no results')}
styles={{
container: {
flex: 0,
},
description: {
color: '#000',
fontSize: 16,
},
predefinedPlacesDescription: {
color: '#3caf50',
},
}}
/>
</SafeAreaView>
);
};
styles prop是一个使用React Native的标准样式属性和值的对象。通过styles 道具,你可以为组成GooglePlacesAutocomplete 组件的不同部分设置样式。
这些部分--如文本输入、下拉容器、每个下拉元素和其他--是GooglePlacesAutocomplete 组件的子元素。例如,对文本输入的样式设计将是这样做的:
styles={
textInput: {
borderColor: 'orange',
fontSize: 20
}
}
你应该尝试根据每个部分或属性的类型来设计其样式。例如,该组件的容器是一个视图组件,因此它应该被样式化为一个视图组件。这里有一个所有部分/属性及其元素类型的列表。
将结果限制在一个国家
可以将react-native-google-places-autocomplete 建议中显示的搜索结果限制在一个国家。这样,只有符合用户在某一国家的搜索字符串的地方才会弹出。
使用查询道具中的组件属性来指定一个国家,像这样:
query={{key: apiKey, components: 'country:us'}}
country:us 这个值只是意味着美国。它使用的是国家名称的缩写,而不是完整的名称。这里有一个支持的国家的列表。
通过查询道具,你也可以提供不同语言的结果。默认的语言是英语,但通过语言属性,你可以用ISO 639-1代码指定不同的语言:
query={{key: apiKey, components: 'country:us', language: 'it'}}
在上面的代码中,我们将language 属性设置为it 。这将提供意大利语的结果。如果你想提供其他语言的搜索结果,请看一下支持的语言及其代码的列表。
现在,如果用户开始搜索,搜索结果将以意大利语出现,并且只显示美国境内的选项。

取回输入值
react-native-google-places-autocomplete 包所提供的方法之一是getAddressText 。这个方法返回用户的文本输入值。
这个方法有很多用例。例如,当搜索一个未知的地方时,以一种特殊的方式显示用户的输入,或者在搜索时发生错误时重新使用用户的最后一次输入。
要使用该包提供的任何方法,我们首先要使用React refs对GooglePlacesAutocomplete 组件进行引用,像这样:
const App = () => {
const placesRef = useRef();
const getAddress = () => {
console.log(placesRef.current?.getAddressText());
};
return (
<SafeAreaView>
<GooglePlacesAutocomplete
placeholder="Type a place"
onPress={(data, details = null) => console.log(data, details)}
query={{key: apiKey}}
fetchDetails={true}
onFail={error => console.log(error)}
onNotFound={() => console.log('no results')}
ref={placesRef}
/>
</SafeAreaView>
);
};
其他可能有用的方法是:
setAddressText:改变文本输入的值clear: 清除文本输入isFocused:如果文本输入被聚焦,则返回true,如果没有则返回false。getCurrentLocation:根据当前位置进行查询,以找到附近的地方。
接下来让我们探讨如何使用getCurrentLocation 。
获取当前位置
getCurrentLocation 方法根据用户的当前位置进行查询,以找到附近的地方。然而,这并不是这个包所提供的唯一的位置功能;它也可以用检索地方信息的同样方式获得用户的当前位置。
该软件包使用地理定位服务来寻找用户的位置,并将其作为自动完成建议的一部分。当选择时,关于用户当前位置的细节将被返回。
为了实现这一点,我们必须将currentLocation 道具设置为true:
const App = () => {
return (
<SafeAreaView>
<GooglePlacesAutocomplete
placeholder="Type a place"
onPress={(data, details = null) => console.log(data, details)}
query={{key: apiKey}}
fetchDetails={true}
onFail={error => console.log(error)}
onNotFound={() => console.log('no results')}
currentLocation={true}
currentLocationLabel="Your location!" // add a simple label
/>
</SafeAreaView>
);
};
这并不是一个完整的应用程序所要设置的全部内容。你还得安装一个地理定位服务提供商,如 [react-native-geolocation-service](https://www.npmjs.com/package/react-native-geolocation-service).
此外,你需要要求你的用户授予位置权限,以使用任何带有react-native-google-places-autocomplete 的位置服务。然而,这些具体步骤超出了本文的范围,本文特别关注react-native-google-places-autocomplete 包。
总结
在这篇文章中,我们看了如何为react-native-google-places-autocomplete 包建立一个谷歌云项目。我们还通过包的道具和方法看了大量的功能。
例如,我们看了处理响应、保护你的API密钥、设计GooglePlacesAutocomplete 组件、将结果限制在一个国家、以不同的语言显示结果、使用getAddressText 等方法、使用自定义文本输入组件,以及其他。
现在,这个包并不限于我们在这里列出的内容。你可以找到更多的道具和方法,这些道具和方法将有助于定制该包,以适应你希望在你的应用程序中使用Google Places API的方式。
我希望你玩得很开心。请在评论区告诉我你的想法。谢谢你的阅读,并祝你黑客生涯愉快。