ReactJS–;如何检查值是否未定义

ReactJS–;如何检查值是否未定义,reactjs,Reactjs,我正在使用Google Places API创建一个“查找最近的餐馆”应用程序。我在一个道具的ResultItem组件中调用背景图像 此图像被定义为代码此部分上方常量中的缩略图。我的代码运行平稳,但在places.photos[0]返回为未定义(意味着Google Place没有上传任何图像)时,我收到一个错误,提示: 未处理的拒绝(TypeError):无法读取未定义的属性“0” 我想我要做的是检查places.photos[0]是否未定义,但我似乎没有弄清楚 我的目标是在该值未定义时显示另一

我正在使用Google Places API创建一个“查找最近的餐馆”应用程序。我在一个道具的ResultItem组件中调用背景图像

此图像被定义为代码此部分上方常量中的缩略图。我的代码运行平稳,但在places.photos[0]返回为未定义(意味着Google Place没有上传任何图像)时,我收到一个错误,提示:

未处理的拒绝(TypeError):无法读取未定义的属性“0”

我想我要做的是检查places.photos[0]是否未定义,但我似乎没有弄清楚

我的目标是在该值未定义时显示另一个占位符图像。如果已经定义,组件应该从GooglePlacesAPI获取图像

有人能帮我吗

完整组件:

import React, { Component } from 'react';

// Imports
import axios from 'axios';
import Script from 'react-load-script';
import Placeholder from './Placeholder.jsx';
import FadeIn from 'react-fade-in';
import {
  Spinner,
  Paragraph,
  SideSheet,
  Tooltip,
  IconButton,
  SearchInput
} from 'evergreen-ui';
import ResultsItem from '../../components/ResultsItem/ResultsItem.jsx';

import Geocode from 'react-geocode';

// Styles
import './Search.scss';

class Autocomplete extends Component {
  // Define Constructor
  constructor(props) {
    super(props);

    // Declare State
    this.state = {
      type: 'restaurant',
      radius: 10,
      lat: '59.0738',
      lng: '41.3226',
      city: '',
      query: '',
      open: false,
      places: [],
      place_detail: [],
      sidebar: false,
      loading: true
    };

    this.currentLocationOnClick = this.currentLocationOnClick.bind(this);
    this.handlePlaceSelect = this.handlePlaceSelect.bind(this);
  }

  currentLocationOnClick = async () => {
    let { lat, lng, places } = this.state;
    const URL = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${lat},${lng}&type=restaurant&radius=${5 *
      1000}&key=MY_API_KEY`;
    navigator.geolocation.getCurrentPosition(
      async position => {
        this.setState({ lat: position.coords.latitude });
        this.setState({ lng: position.coords.longitude });

        const URL = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${
          position.coords.latitude
        },${position.coords.longitude}&type=restaurant&radius=${5 *
          1000}&key=MY_API_KEY`;

        const response = await axios.get(URL);
        console.log(response.data);
        places = response.data.results;
        this.setState({ places });
      },
      error => {
        console.log('Error getting location');
      }
    );
  };

  async componentDidMount() {
    const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=
    ${this.state.lat},${this.state.lng}type=restaurant&radius=${2 *
      1000}&key=MY_API_KEYE`;
    const response = await fetch(url);
    const data = await response.json();
    this.setState({ places: data.results });
    console.log(data.results);
  }

  handleScriptLoad = () => {
    // Declare Options For Autocomplete
    const options = {
      types: ['address']
    }; // To disable any eslint 'google not defined' errors

    // Initialize Google Autocomplete
    /*global google*/ this.autocomplete = new google.maps.places.Autocomplete(
      document.getElementById('autocomplete'),
      options
    );

    // Avoid paying for data that you don't need by restricting the set of
    // place fields that are returned to just the address components and formatted
    // address.
    this.autocomplete.setFields(['address_components', 'formatted_address']);

    // Fire Event when a suggested name is selected
    this.autocomplete.addListener('place_changed', this.handlePlaceSelect);
  };

  handlePlaceSelect = async () => {
    let { query, lat, lng } = this.state;

    this.setState({ loading: true });

    // Extract City From Address Object
    const addressObject = this.autocomplete.getPlace();
    const address = addressObject.address_components;

    Geocode.setApiKey('MY_API_KEY');

    // Check if address is valid
    let city;
    if (address) {
      city = address[0].long_name;
      query = addressObject.formatted_address;
    }

    try {
      const response = await Geocode.fromAddress(query);
      ({ lat, lng } = response.results[0].geometry.location);
    } catch (error) {
      console.error(error);
    }

    let places;
    try {
      const URL = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${lat},${lng}&type=restaurant&radius=${5 *
        1000}&key=MY_API_KEY`;
      const response = await axios.get(URL);
      console.log(response.data);
      places = response.data.results;
    } catch (error) {
      console.log(error.message);
    }

    this.setState({ query, places, city, lat, lng });
    setTimeout(() => this.setState({ loading: false }), 400);
  };

  render() {
    const { loading } = this.state;

    return (
      <div>
        <div className="flex align-center">
          <div className="search">
            <SearchInput
              id="autocomplete"
              placeholder="Search by address"
              width="100%"
              height={56}
            />
            <Script
              url="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&libraries=places,geometry&callback=initAutocomplete"
              onLoad={this.handleScriptLoad}
            />
          </div>

          <div className="current-location">
            <Tooltip content="Use current location">
              <IconButton
                icon="locate"
                iconSize={16}
                height={32}
                onClick={this.currentLocationOnClick}
              >
                {this.state.lat} & {this.state.lng}
              </IconButton>
            </Tooltip>
          </div>
        </div>

        <div className="results">
          {this.state.places.map(places => {
            const Thumbnail = `https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=${places.photos[0].photo_reference}&key=MY_API_KEY
    `;
            return (
              <div
                className="results-flex"
                onClick={async () => {
                  let loading;
                  let sidebar;
                  let place_detail;
                  try {
                    const URL = `https://maps.googleapis.com/maps/api/place/details/json?place_id=${places.place_id}&fields=name,rating,formatted_phone_number&key=
                    MY_API_KEY`;
                    const response = await axios.get(URL);
                    console.log(response.data);
                    place_detail = response.data.result;
                  } catch (error) {
                    console.log(error.message);
                  }

                  this.setState(
                    { place_detail, sidebar: true }
                    // () => this.props.sideBarOpen()
                  );
                }}
              >
                {this.state.loading ? (
                  <>
                    <div className="flex justify-center">
                      <Placeholder />
                    </div>
                  </>
                ) : (
                  <FadeIn>
                    <ResultsItem
                      name={places.name}
                      image={Thumbnail}
                      rating={places.rating}
                      rating_total={places.user_ratings_total}
                    />
                  </FadeIn>
                )}
              </div>
            );
          })}

          <SideSheet
            isShown={this.state.sidebar}
            onCloseComplete={() => this.setState({ sidebar: false })}
          >
            <Paragraph margin={40}>{this.state.place_detail.name}</Paragraph>
          </SideSheet>
        </div>
      </div>
    );
  }
}

export default Autocomplete;
import React,{Component}来自'React';
//进口
从“axios”导入axios;
从“反应加载脚本”导入脚本;
从“./Placeholder.jsx”导入占位符;
从“反应淡入”导入淡入;
进口{
纺纱机,
段落
侧页,
工具提示,
IconButton,
搜索输入
}来自“常青ui”;
从“../../components/ResultsItem/ResultsItem.jsx”导入ResultsItem;
从“react Geocode”导入地理编码;
//风格
导入“/Search.scss”;
类自动完成扩展组件{
//定义构造函数
建造师(道具){
超级(道具);
//申报国家
此.state={
类型:'餐厅',
半径:10,
纬度:'59.0738',
液化天然气:“41.3226”,
城市:'',
查询:“”,
开:错,
地点:[],
地点详情:[],
边栏:错,
加载:正确
};
this.currentLocationOnClick=this.currentLocationOnClick.bind(this);
this.handlePlaceSelect=this.handlePlaceSelect.bind(this);
}
currentLocationOnClick=async()=>{
设{lat,lng,places}=this.state;
常量URL=`https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${lat},${lng}&type=餐厅&radius=${5*
1000}&key=MY_API_key`;
navigator.geolocation.getCurrentPosition(
异步位置=>{
this.setState({lat:position.coords.latitude});
this.setState({lng:position.coords.longitude});
常量URL=`https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${
位置坐标纬度
},${position.coords.longitude}&type=restaurant&radius=${5*
1000}&key=MY_API_key`;
const response=wait axios.get(URL);
console.log(response.data);
地点=响应、数据、结果;
this.setState({places});
},
错误=>{
log(“获取位置时出错”);
}
);
};
异步组件didmount(){
常量url=`https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=
${this.state.lat},${this.state.lng}type=restaurant&radius=${2*
1000}&key=MY_API_KEYE`;
const response=等待获取(url);
const data=wait response.json();
this.setState({places:data.results});
console.log(data.results);
}
handleScriptLoad=()=>{
//声明自动完成的选项
常量选项={
类型:[“地址”]
};//禁用任何eslint“google未定义”错误
//初始化Google自动完成
/*全局google*/this.autocomplete=new google.maps.places.autocomplete(
document.getElementById('autocomplete'),
选择权
);
//通过限制数据集,避免为不需要的数据付费
//放置仅返回到地址组件并格式化的字段
//地址。
this.autocomplete.setFields(['address\u components','formatted\u address']);
//选择建议名称时引发事件
this.autocomplete.addListener('place\u changed',this.handlePlaceSelect);
};
handlePlaceSelect=async()=>{
设{query,lat,lng}=this.state;
this.setState({loading:true});
//从地址对象中提取城市
const addressObject=this.autocomplete.getPlace();
常量地址=addressObject.address\u组件;
Geocode.setApiKey('MY_API_KEY');
//检查地址是否有效
让城市;
如果(地址){
城市=地址[0]。长\名;
query=addressObject.formatted\u地址;
}
试一试{
const response=wait Geocode.fromAddress(查询);
({lat,lng}=response.results[0].geometry.location);
}捕获(错误){
控制台错误(error);
}
让地方;
试一试{
常量URL=`https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${lat},${lng}&type=餐厅&radius=${5*
1000}&key=MY_API_key`;
const response=wait axios.get(URL);
console.log(response.data);
地点=响应、数据、结果;
}捕获(错误){
console.log(错误消息);
}
this.setState({query,places,city,lat,lng});
setTimeout(()=>this.setState({loading:false}),400);
};
render(){
const{loading}=this.state;
返回(
{this.state.lat}&{this.state.lng}
{this.state.places.map(places=>{
常量缩略图=`https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=${places.photos[0].photo\u reference}&key=MY\u API\u key
`;
返回(
{
让加载;
让边栏;
让我们把细节放在一起;
试一试{
常量URL=`https://maps.googleapis.com/maps/api/place/details/json?place_id=${places.place\u id}&fields=名称、等级、格式化的电话号码和键=
我的API密钥`;
const response=wait axios.get(URL);
日志(响应)。
if(!!places.photos[0]) {   
const Thumbnail =
`https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=${places.photos[0].photo_reference}&key=MY_API_KEY
}
else { const Thumbnail = `another image url` }