当标记放置在不同的位置时,如何阻止Google地图重新呈现并仅将值保留在输入字段中? [英] How to stop the google map from re rendering and keeping just the values in input fields when marker is placed on different locations?

查看:107
本文介绍了当标记放置在不同的位置时,如何阻止Google地图重新呈现并仅将值保留在输入字段中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I did a lot of research on this but i am not getting any solutions so please look through and help me, Basically its like when we select a location on the map by dragging the marker ,i don't want the map to refresh and reset the values and also the pin is coming back to the center after re render takes place,

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

Is there any solution in "shouldcomponentupdate" ?? which doesn't allow you to re render the whole thing but by keep updating the values which were retrieved like address ,lat and long in input field when i move the marker from one locaton to another!!

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

And also i tried different things in shouldcomponentupdate method like by returning it as false , but over there map was not re rendering i could drag the pin from where i left off , i could see the locations getting updated in the console below , but values of those locations were not displaying in the input fields provided !

简而言之,如果我要说的话,每当我将大头针拖放到位置时,都必须连续检索位置值,而大头针不会回到地图的中心,这样我才能从该位置继续检索位置我把标记销钉留在了地图上.

In simple words if i want to say, whenever i drag and drop the pin on location ,location value must be retrieved continuous without the pin coming back to the center of the map, so that i can resume retrieving of location from where i left the marker pin on the map .

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

Please Help Me out !! I took this code from the net i want to implement those bit of changes

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

推荐答案

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

I was searching solution for the same issue, when I found your question. I know its late post, but my answer will help those who are getting here. shouldComponentUpdate() method is used to avoid unnecessary renders of the component. So, we have to place conditions in this method so as to return true or false based on that. In your code - replace the shouldcomponentupdate method as follows:

    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
    }
}

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

That worked for me. Hope that helps. Thank you!

这篇关于当标记放置在不同的位置时,如何阻止Google地图重新呈现并仅将值保留在输入字段中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆