根据道具提出条件Api请求

时间:2018-10-22 20:13:56

标签: javascript reactjs fetch

我有一个极简的登录页面,其中包含两个文本和一个div,其中包含两个按钮。单击其中一个按钮时,我想使用传递为prop的位置或硬编码到App组件中的默认位置来渲染App组件。

如果已按如下所示单击了第一个按钮,则我已经到达位置using GeoLocation API and window navigator,并将其传递到App组件中:

if (this.state.shouldShowMain){
        return ( <App/> ) // no props
    } else if (this.state.shouldShowMainWithProps){
        const { lat, lng } = this.state.mLocation;
        return ( <App
            latitude={lat}
            longitude={lng} // props to App component
        />)
    }

我的状态对象是这样的:

this.state = {
        mLocation: {
            lat: '',
            lng: ''
        },
        isFromLocation: false,
        shouldShowMain: false,
        shouldShowMainWithProps: false
    };

并且在App组件中,我试图在进行api调用以提取标记之前,区分这两种状态:

 componentDidMount() {

    if (this.props){
        const { latitude, longitude } = this.props;
        // console.log(this.props);

        fetch(
            // 'https://api.foursquare.com/v2/venues/search?ll= 12.917137,77.622791' +
            'https://api.foursquare.com/v2/venues/search?ll=' + latitude + ',' + longitude +
            '&query=atm&client_id=LVN4FEBT5Q0DBIQ2JOP4KYZ1LOEXREFRLOXV5UXAQWHUF14V' +
            '&client_secret=HZRYTMFJRS4N0R50IEZR04JXSO1KWVJWC015VTYLCCCG3C0U&v=20181101')
            .then(response => response.json())
            .then(data => {

                const atms = data.response.venues;
                const markers = atms.map( (item) => {
                    return {
                        lat: item.location.lat,
                        lng: item.location.lng
                    }
                });

                this.setState({
                    atms,
                    markers
                })
            })
            .catch(err => {
                this.setState({apiError: true});
                throw err;
            });
    } else {
        // no probs, fetching from silk board

        fetch(
            // 'https://api.foursquare.com/v2/venues/search?ll=' + latitude + ',' + longitude +
            'https://api.foursquare.com/v2/venues/search?ll= 12.917137,77.622791' +
            '&query=atm&client_id=LVN4FEBT5Q0DBIQ2JOP4KYZ1LOEXREFRLOXV5UXAQWHUF14V' +
            '&client_secret=HZRYTMFJRS4N0R50IEZR04JXSO1KWVJWC015VTYLCCCG3C0U&v=20181101')
            .then(response => response.json())
            .then(data => {

                const atms = data.response.venues;
                const markers = atms.map( (item) => {
                    return {
                        lat: item.location.lat,
                        lng: item.location.lng
                    }
                });

                this.setState({
                    atms,
                    markers
                })
            })
            .catch(err => {
                this.setState({apiError: true});
                throw err;
            });
    }

}

我测试的情况是,当我选择获取位置的按钮时,它将获取App组件中的硬编码位置,即else部分,并且当我单击没有道具的按钮时,该应用崩溃因为它期望确实不应该有的价值。

它以相反的方式工作,因此api调用失败。我该如何解决?我愿意编辑问题以适应所要求的任何细节。谢谢。

基于良好的建议,我已经收到问题已解决一半的信息。现在的问题是从坐标绘制正确的地图。这是我的实现:

<div className="mapContainer">

                    <MapView
                        atms={this.state.atms},
                        markers={this.state.markers}
                        apiError={this.state.apiError}
                        filteredAtms={filteredAtms}/>
                </div>

MapView中的标记属性来自then in response from api,而MapView component中的标记属性为默认标记中心:

const MyCity = withGoogleMap(props => (
        <GoogleMap
            defaultCenter={{lat: 12.917137, lng: 77.622791}}
            defaultZoom={15}>

            {/*{<Marker position={{lat: 12.917137, lng: 77.622791}}/>}*/}

            {this.props.markers && this.props.markers.map( (marker, index) =>
                <Marker
                    key={index}
                    position={{lat: marker.lat, lng: marker.lng}}/>
             )}

        </GoogleMap>

    ));

我该如何适应?我是否使用相同的方法在此组件上设置默认道具或另一种方法。谢谢。

3 个答案:

答案 0 :(得分:1)

您可以为App组件定义defualProps,然后,如果不向组件传递纬度和经度,它将使用默认值。

RTL

答案 1 :(得分:1)

您可以传递@ oliver.voron中提到的默认Props,或者做一些简单的事情:

const latitude = this.props.latitude || 'defaultLatitude';
const longitude = this.props.longitude || 'defaultLongitude';

答案 2 :(得分:1)

您可以像这样渲染App组件:

const { lat, lng } = this.state.mLocation;
return (
    <App latitude={lat} longitude={lng}/>
);

然后在App组件中,如果这些值为undefined,它将回退到默认值。

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            latitude: this.props.latitude || 123.45 // default value
            longitude: this.props.longitude || 456.78 // default value
        };
    }
    componentDidMount() {
        const { latitude, longitude } = this.state;
        fetch('https://api.foursquare.com/v2/venues/search?ll=' + latitude + ',' + longitude +
            // other code...
    }
}