当标记放置在不同位置时,如何阻止Google地图重新呈现并仅将值保留在输入字段中?

问题描述 投票:0回答:1

我对此进行了大量研究,但仍未找到任何解决方案,因此请仔细阅读并提供帮助,基本上就像当我们通过拖动标记在地图上选择一个位置时,我不希望地图刷新并重置值,并且重新渲染发生后,图钉又回到中心,

“ shouldcomponentupdate”中有什么解决方案吗?这不允许您重新渲染整个内容,但是当我将标记从一个位置移动到另一个位置时,通过不断更新在输入字段中检索到的值(例如address,lat和long),就可以了!

而且我还应该在shouldcomponentupdate方法中尝试其他操作,例如将其返回为false,但是在那边地图没有重新渲染,我可以将销钉从我停下来的地方拖出来,我可以在下面的控制台中看到更新的位置,但是这些位置的值未显示在提供的输入字段中!

用简单的话来说,只要我将大头针拖放到位置上,就必须连续检索位置值,而大头针不会回到地图中心,这样我就可以从我的位置继续检索位置将标记图钉留在地图上。

请帮帮我!!我从网上获取了这段代码,我想实现这些更改

import React, { Component } from 'react';
import { withGoogleMap, GoogleMap, withScriptjs, InfoWindow, Marker } from "react-google-maps";
import Geocode from "react-geocode";
import Autocomplete from 'react-google-autocomplete';
Geocode.setApiKey( "AIzaSyDGe5vjL8wBmilLzoJ0jNIwe9SAuH2xS_0" );
Geocode.enableDebug();

class Map extends Component{

constructor( props ){
    super( props );
    this.state = {
        address: '',
        city: '',
        area: '',
        state: '',
        mapPosition: {
            lat: this.props.center.lat,
            lng: this.props.center.lng
        },
        markerPosition: {
            lat: this.props.center.lat,
            lng: this.props.center.lng
        }
    }
}
/**
 * Get the current address from the default map position and set those values in the state
 */
componentDidMount() {
    Geocode.fromLatLng( this.state.mapPosition.lat , this.state.mapPosition.lng ).then(
        response => {
            const address = response.results[0].formatted_address,
                addressArray =  response.results[0].address_components,
                city = this.getCity( addressArray ),
                area = this.getArea( addressArray ),
                state = this.getState( addressArray );

            console.log( 'city', city, area, state );

            this.setState( {
                address: ( address ) ? address : '',
                area: ( area ) ? area : '',
                city: ( city ) ? city : '',
                state: ( state ) ? state : '',
            } )
        },
        error => {
            console.error( error );
        }
    );
};
/**
 * Component should only update ( meaning re-render ), when the user selects the address, or drags the pin
 *
 * @param nextProps
 * @param nextState
 * @return {boolean}
 */


shouldComponentUpdate( nextProps, nextState ){
        if (
            this.state.markerPosition.lat !== this.props.center.lat ||
            this.state.address !== nextState.address ||
            this.state.city !== nextState.city ||
            this.state.area !== nextState.area ||
            this.state.state !== nextState.state
        ) {
            return true
        } else if ( this.props.center.lat === nextProps.center.lat ){
            return false
        }
    }
/**
 * Get the city and set the city input value to the one selected
 *
 * @param addressArray
 * @return {string}
 */
getCity = ( addressArray ) => {
    let city = '';
    for( let i = 0; i < addressArray.length; i++ ) {
        if ( addressArray[ i ].types[0] && 'administrative_area_level_2' === addressArray[ i ].types[0] ) {
            city = addressArray[ i ].long_name;
            return city;
        }
    }
};
/**
 * Get the area and set the area input value to the one selected
 *
 * @param addressArray
 * @return {string}
 */
getArea = ( addressArray ) => {
    let area = '';
    for( let i = 0; i < addressArray.length; i++ ) {
        if ( addressArray[ i ].types[0]  ) {
            for ( let j = 0; j < addressArray[ i ].types.length; j++ ) {
                if ( 'sublocality_level_1' === addressArray[ i ].types[j] || 'locality' === addressArray[ i ].types[j] ) {
                    area = addressArray[ i ].long_name;
                    return area;
                }
            }
        }
    }``
};
/**
 * Get the address and set the address input value to the one selected
 *
 * @param addressArray
 * @return {string}
 */
getState = ( addressArray ) => {
    let state = '';
    for( let i = 0; i < addressArray.length; i++ ) {
        for( let i = 0; i < addressArray.length; i++ ) {
            if ( addressArray[ i ].types[0] && 'administrative_area_level_1' === addressArray[ i ].types[0] ) {
                state = addressArray[ i ].long_name;
                return state;
            }
        }
    }
};
/**
 * And function for city,state and address input
 * @param event
 */
onChange = ( event ) => {
    this.setState({ [event.target.name]: event.target.value });
};
/**
 * This Event triggers when the marker window is closed
 *
 * @param event
 */
onInfoWindowClose = ( event ) => {

};

/**
 * When the marker is dragged you get the lat and long using the functions available from event object.
 * Use geocode to get the address, city, area and state from the lat and lng positions.
 * And then set those values in the state.
 *
 * @param event
 */
onMarkerDragEnd = ( event ) => {
    let newLat = event.latLng.lat(),
        newLng = event.latLng.lng();

    Geocode.fromLatLng( newLat , newLng ).then(
        response => {
            const address = response.results[0].formatted_address,
                addressArray =  response.results[0].address_components,
                city = this.getCity( addressArray ),
                area = this.getArea( addressArray ),
                state = this.getState( addressArray );
            this.setState( {
                address: ( address ) ? address : '',
                area: ( area ) ? area : '',
                city: ( city ) ? city : '',
                state: ( state ) ? state : ''
            } )
        },
        error => {
            console.error(error);
        }
    );
};

/**
 * When the user types an address in the search box
 * @param place
 */
onPlaceSelected = ( place ) => {
    console.log( 'plc', place );
    const address = place.formatted_address,
        addressArray =  place.address_components,
        city = this.getCity( addressArray ),
        area = this.getArea( addressArray ),
        state = this.getState( addressArray ),
        latValue = place.geometry.location.lat(),
        lngValue = place.geometry.location.lng();
    // Set these values in the state.
    this.setState({
        address: ( address ) ? address : '',
        area: ( area ) ? area : '',
        city: ( city ) ? city : '',
        state: ( state ) ? state : '',
        markerPosition: {
            lat: latValue,
            lng: lngValue
        },
        mapPosition: {
            lat: latValue,
            lng: lngValue
        },
    })
};


render(){
    const AsyncMap = withScriptjs(
        withGoogleMap(
            props => (
                <GoogleMap google={ this.props.google }
                           defaultZoom={ this.props.zoom }
                           defaultCenter={{ lat: this.state.mapPosition.lat, lng: this.state.mapPosition.lng }}
                >
                    {/* InfoWindow on top of marker */}
                    <InfoWindow
                        onClose={this.onInfoWindowClose}
                        position={{ lat: ( this.state.markerPosition.lat + 0.0018 ), lng: this.state.markerPosition.lng }}
                    >
                        <div>
                            <span style={{ padding: 0, margin: 0 }}>{ this.state.address }</span>
                        </div>
                    </InfoWindow>
                    {/*Marker*/}
                    <Marker google={this.props.google}
                            name={'Dolores park'}
                            draggable={true}
                            onDragEnd={ this.onMarkerDragEnd }
                            position={{ lat: this.state.markerPosition.lat, lng: this.state.markerPosition.lng }}
                    />
                    <Marker />
                    {/* For Auto complete Search Box */}
                    <Autocomplete
                        style={{
                            width: '100%',
                            height: '40px',
                            paddingLeft: '16px',
                            marginTop: '2px',
                            marginBottom: '100px'
                        }}
                        onPlaceSelected={ this.onPlaceSelected }
                        types={['(regions)']}
                    />
                </GoogleMap>
            )
        )
    );
    let map;
    if( this.props.center.lat !== undefined ) {
        map = <div>
            <div>
                <div className="form-group">
                    <label htmlFor="">City</label>
                    <input type="text" name="city" className="form-control" onChange={ this.onChange } readOnly="readOnly" value={ this.state.city }/>
                </div>
                <div className="form-group">
                    <label htmlFor="">Area</label>
                    <input type="text" name="area" className="form-control" onChange={ this.onChange } readOnly="readOnly" value={ this.state.area }/>
                </div>
                <div className="form-group">
                    <label htmlFor="">State</label>
                    <input type="text" name="state" className="form-control" onChange={ this.onChange } readOnly="readOnly" value={ this.state.state }/>
                </div>
                <div className="form-group">
                    <label htmlFor="">Address</label>
                    <input type="text" name="address" className="form-control" onChange={ this.onChange } readOnly="readOnly" value={ this.state.address }/>
                </div>
            </div>

            <AsyncMap
                googleMapURL="https://maps.googleapis.com/maps/api/js?key=AIzaSyDGe5vjL8wBmilLzoJ0jNIwe9SAuH2xS_0&libraries=places"
                loadingElement={
                    <div style={{ height: `100%` }} />
                }
                containerElement={
                    <div style={{ height: this.props.height }} />
                }
                mapElement={
                    <div style={{ height: `100%` }} />
                }
            />
        </div>
    } else {
        map = <div style={{height: this.props.height}} />
    }
    return( map )
}
}

export default Map
reactjs google-maps geocode react-component react-google-maps
1个回答
0
投票

当我发现您的问题时,我正在寻找相同问题的解决方案。我知道它的帖子很晚,但是我的回答将对那些来这里的人有所帮助。shouldComponentUpdate()方法用于避免不必要的组件渲染。因此,我们必须在此方法中放置条件,以便基于该条件返回true或false。在您的代码中,按如下所示替换shouldcomponentupdate方法:

    shouldComponentUpdate( nextProps, nextState ){
    if (
    this.state.markerPosition.lat !== this.props.center.lat ||
    this.state.address !== nextState.address 
    ) {
    return false
    } else if ( this.props.center.lat === nextProps.center.lat ){
    return true
    }
}

对我有用。希望能有所帮助。谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.