first time getting undefined props from mapStateToProps

被刻印的时光 ゝ 提交于 2020-02-06 07:24:05

问题


how can i get asynchronous reducers data ,i search but didn't get solution
Booking component

    cutPick = () => {

            this.props.pickup(false);

        }

action creator

export function pickup(latlng) {

    return function (dispatch) {

        dispatch({type:PICKUP_STATE,payload:latlng});
    }

}

reducer

import {PICKUP_STATE} from '../actions/types';

export default function (state={},action) {

    switch(action.type) {
        case PICKUP_STATE:

            return {...state,pickup:action.payload}
    }
    return state;
}

Map component

import React from 'react';
import scriptLoader from "react-async-script-loader";
import config from '../../../config'
import 'antd/dist/antd.css';
import {  Icon,Button,Alert,Row, Col} from 'antd';
import {connect} from "react-redux";
import * as actions from "../actions";

class Map extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            pick:false,
            drop:false,
            mapCenter : { lat: 17.3850, lng: 78.4867 },
            pickupConfirmButton:false,
            dropoffConfirmButton:false
        };
        this.map=false;
        this.directionsService =false;
        this.directionsDisplay = false;
        this.mapLoaded = false;
        this.pickMarker=false;
        this.dropMarker=false;
    }

    //listen map current location event and set marker and pick state
    addYourLocationButton = (map) => {

            this.pickMarker = new google.maps.Marker   ({
                map: this.map,
                animation: google.maps.Animation.DROP,
                position: this.state.pick ? this.state.pick : this.state.mapCenter,
                draggable: true
            });

        if(!this.mapLoaded) {
            return false;
        }
        var controlDiv = document.createElement('div');

        let firstChild = document.createElement('button');
        firstChild.style.backgroundColor = '#fff';
        firstChild.style.border = 'none';
        firstChild.style.outline = 'none';
        firstChild.style.width = '28px';
        firstChild.style.height = '28px';
        firstChild.style.borderRadius = '2px';
        firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)';
        firstChild.style.cursor = 'pointer';
        firstChild.style.marginRight = '10px';
        firstChild.style.padding = '0px';
        firstChild.title = 'Your Location';
        controlDiv.appendChild(firstChild);

        let secondChild = document.createElement('div');
        secondChild.style.margin = '5px';
        secondChild.style.width = '18px';
        secondChild.style.height = '18px';
        secondChild.style.backgroundImage = 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-1x.png)';
        secondChild.style.backgroundSize = '180px 18px';
        secondChild.style.backgroundPosition = '0px 0px';
        secondChild.style.backgroundRepeat = 'no-repeat';
        secondChild.id = 'you_location_img';
        firstChild.appendChild(secondChild);

        // google.maps.event.addListener(map, 'dragend',  () => {
        //     document.getElementById("you_location_img").style.backgroundPosition='0px 0px';
        // });
        google.maps.event.addListener(this.pickMarker, 'dragend', () =>{

            let lat=this.pickMarker.getPosition().lat();
            let lng=this.pickMarker.getPosition().lng();

            this.setState({pick:{lat:lat,lng:lng}},function () {
                let geocoder = new google.maps.Geocoder;
                geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
                    if (status === 'OK') {
                        document.getElementById('pick').value = results[0].formatted_address;
                    }
                })
                // console.log(this.state.pick);
            })
            if (this.state.pick && this.state.drop){
                this.calculateRoute();
            }
        });
        firstChild.addEventListener('click',  () => {
            let imgX = '0';
            let animationInterval = setInterval( () =>{
                if (imgX == '-18') imgX = '0';
                else imgX = '-18';
                document.getElementById("you_location_img").style.backgroundPosition=imgX + 'px 0px';
            }, 500);

            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition( (position) => {
                    let latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                    let geocoder = new google.maps.Geocoder;
                    geocoder.geocode({'location': latlng}, function(results, status) {
                        if (status === 'OK') {
                            document.getElementById('pick').value = results[0].formatted_address;
                        }
                    })
                    if(latlng){
                        this.setState(()=>({
                            pick:latlng
                        }))
                    }
                    this.pickMarker.setPosition(latlng);
                    map.setCenter(latlng);
                    if (this.state.pick && this.state.drop){
                        this.calculateRoute();
                    }

                    clearInterval(animationInterval);
                    document.getElementById("you_location_img").style.backgroundPosition='-144px 0px';
                });
            }
            else {
                clearInterval(animationInterval);
                document.getElementById("you_location_img").style.backgroundPosition='0px 0px';
            }
        });

        controlDiv.index = 1;
        map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(controlDiv);
    }

    //load gmaps ,load maps and directions and set center as user current location
    componentWillReceiveProps({isScriptLoadSucceed}){
        if (isScriptLoadSucceed) {
            this.mapLoaded= true;
            this.directionsService = new google.maps.DirectionsService();
            this.directionsDisplay = new google.maps.DirectionsRenderer({ suppressMarkers: true });


            this.map = new google.maps.Map(document.getElementById('map'), {
                zoom: 11,
                center: this.state.mapCenter
            });
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition( (position)=> {
                    let initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                    // console.log(this.state.mapCenter)

                    this.setState({mapCenter:initialLocation} , ()=> {
                        // console.log(this.state.mapCenter)
                    })
                    this.map.setCenter(initialLocation);
                });
            }else{
                console.log('error in current location')
            }

            this.directionsDisplay.setMap(this.map);

            //icon of current location in map and current loc pickup marker
            this.addYourLocationButton(this.map);

            //listener for pickup marker when it clicked
            this.pickMarker.addListener('click', () =>{
                this.pickupMarkerClickListener();
            });

        }
        else{
            alert("Something went wrong, plz check internet Connection")
        }
    }
    //for Refs
    componentDidMount() {
        this.props.onRef(this);
    }
    //for Refs
    componentWillUnmount() {
        this.props.onRef(null);
    }


    // this function pick state false when user click on cut pick address from pickup field and set direction false also
    isPickEmpty=(emptyPickState)=>{

        console.log(this.props.pickupProps);
        this.setState({pick:emptyPickState},function () {
            this.pickMarker.setMap(null);
            this.directionsDisplay.set('directions', null);
            //sending false as distance to BookingDetails
            this.props.routeCalc(false);
        });

    };

    //it handle search hint of google place api (getting data from Booking Form)
    pickupSearch =(pickupAddress) =>{
        let options = {
            types: [],
            componentRestrictions: {
                'country': 'IN'
            }
        };
        let inputPick = document.getElementById('pick');
        const autocompletePick = new google.maps.places.Autocomplete(inputPick, options);
        autocompletePick.bindTo('bounds', this.map);

        google.maps.event.addListener(autocompletePick, 'place_changed',  () => {
            let place =autocompletePick.getPlace();
            let lat = place.geometry.location.lat(),
                lng = place.geometry.location.lng();
            let geocoder = new google.maps.Geocoder;
            geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
                if (status === 'OK') {
                    document.getElementById('pick').value = results[0].formatted_address;
                }
            });
            this.pickUp({lat:lat,lng:lng})
        });
    }

    //this function put pick marker on pickup search
    pickUp = (pick) => {
        // console.log(pick)
        if(this.pickMarker){
            this.pickMarker.setMap(null);
        }

        this.setState({pick:pick}, () => {
            // console.log(this.state.pick);
            var infoWindow = new google.maps.InfoWindow;
            this.pickMarker = new google.maps.Marker({
                map:this.map,
                animation: google.maps.Animation.DROP,
                position: this.state.pick,
                draggable: true
            });
            infoWindow.setPosition(this.state.pick);
            // infoWindow.setContent('Location found.');
            // infoWindow.open(this.map);
            this.map.setCenter(this.state.pick);

            this.pickMarker.addListener('click', () =>{
                this.pickupMarkerClickListener();
            });

            google.maps.event.addListener(this.pickMarker, 'dragend', () =>{
                this.pickupMarkerDragListener();

            });
            this.focus.scrollIntoView();
        })
        if (this.state.pick && this.state.drop){
            this.calculateRoute();
        }
    };

    //this function invoke click and drag function of pickup marker
    pickupMaker=()=>{

        this.setState({pickupConfirmButton:false});
        this.map.setZoom(11);
        if(this.pickMarker){
            this.pickMarker.setMap(null);
        }

        google.maps.event.clearListeners(this.map, 'center_changed');

        this.pickMarker = new google.maps.Marker   ({
            map: this.map,
            animation: google.maps.Animation.DROP,
            position: this.state.pick,
            draggable:true
        });

        if(this.dropMarker){
            this.dropMarker.setVisible(true);
        }

        //listening on drag of pick marker
        google.maps.event.addListener(this.pickMarker, 'dragend', () => {
            this.pickupMarkerDragListener();
            console.log('marker')

        });

        //listening on click of pick marker
        this.pickMarker.addListener('click', () =>{
            this.pickupMarkerClickListener();
        });

        //if both state are set the calculate the root
        if (this.state.pick && this.state.drop){
            this.calculateRoute();
        }
    };

    //this function handle click event of pick Marker
    pickupMarkerClickListener = () => {
        if(this.dropMarker){
            this.dropMarker.setVisible(false);
        }
        this.directionsDisplay.set('directions', null);
        this.setState({pickupConfirmButton:true});
        this.map.setCenter(this.pickMarker.getPosition());
        this.map.setZoom(16);

        this.map.addListener('center_changed',  () => {
            let lat=this.map.getCenter().lat();
            let lng=this.map.getCenter().lng();

            this.setState({pick:{lat:lat,lng:lng}},function () {
                let geocoder = new google.maps.Geocoder;
                geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
                    if (status === 'OK') {
                        document.getElementById('pick').value = results[0].formatted_address;
                    }
                })
                // console.log(this.state.pick);
            });
            this.pickMarker.setPosition({lat:lat,lng:lng});
            // console.log(this.map.getCenter().lat(),this.map.getCenter().lng(),this.pickMarker.getPosition())

        });
    };

    //This function Handle drage event of pick marker
    pickupMarkerDragListener = () => {
        console.log('dragged');
        let lat=this.pickMarker.getPosition().lat();
        let lng=this.pickMarker.getPosition().lng();

        this.setState({pick:{lat:lat,lng:lng}}, () => {
            let geocoder = new google.maps.Geocoder;
            geocoder.geocode({'location': {lat:lat,lng:lng}}, (results, status) => {
                if (status === 'OK') {
                    document.getElementById('pick').value = results[0].formatted_address;
                }
            })
            console.log(this.state.pick);
        })
        if ((this.state.pick && this.state.drop) && (this.state.pickupConfirmButton === false && this.state.dropoffConfirmButton ===false)){
            this.calculateRoute();
        }
    }


    // this function drop state false when user click on cut drop address from dropoff field and set direction false also
    isDropEmpty=(emptyDropState)=>{
        // console.log(emptyPickState);
        // console.log(this.state.pick);
        this.setState({drop:emptyDropState},function () {
            // this.pickMarker=false;
            this.dropMarker.setMap(null);
            this.directionsDisplay.set('directions', null);
            //sending false as distance to BookingDetails
            this.props.routeCalc(false);
        });

    };

    //it handle drop search hint of google place api (getting data from Booking Form)
    dropoffSearch = (dropoffSearch) =>{
        let options = {
            types: [],
            componentRestrictions: {
                'country': 'IN'
            }
        };

        const autocompleteDrop = new google.maps.places.Autocomplete(document.getElementById('drop'), options);
        autocompleteDrop.bindTo('bounds', this.map);

        google.maps.event.addListener(autocompleteDrop, 'place_changed',  () => {
            let place =autocompleteDrop.getPlace();
            let lat = place.geometry.location.lat(),
                lng = place.geometry.location.lng();
            // this.props.dropHandler({lat:lat,lng:lng})
            //
            // this.setState({drop:place.name});
            // let lat = place.geometry.location.lat(),
            //     lng = place.geometry.location.lng();
            //putting place in pick field
            let geocoder = new google.maps.Geocoder;
            geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
                if (status === 'OK') {
                    // console.log(results[0].formatted_address)
                    document.getElementById('drop').value = results[0].formatted_address;
                }
            });
            this.dropOff({lat:lat,lng:lng})
        });
    };

    //this function put drop marker on dropoff search(function invoked from Booking Details)
    dropOff = (drop) => {
        if (this.dropMarker){
            this.dropMarker.setMap(null);
        }
        this.setState({drop:drop}, () => {
            // console.log(this.state.drop);
            var infoWindow = new google.maps.InfoWindow;
            this.dropMarker = new google.maps.Marker({
                map:this.map,
                animation: google.maps.Animation.DROP,
                position: this.state.drop,
                draggable: true
            });
            infoWindow.setPosition(this.state.drop);
            // infoWindow.setContent('Location found.');
            // infoWindow.open(this.map);
            this.map.setCenter(this.state.drop);
            // console.log(this.state.drop);
            google.maps.event.addListener(this.dropMarker, 'dragend', () =>{

                this.dropoffMarkerDragListener();


            });
            this.dropMarker.addListener('click', () =>{
                this.dropoffMarkerClickListener();
            });

            if (this.state.pick && this.state.drop){
                this.calculateRoute();
            }
            this.focus.scrollIntoView();
        })

        // if (this.state.pick && this.state.drop){
        //     this.calculateRoute();
        // }
    };

    //this function invoke click and drag function of drop marker
    dropoffMaker= () =>{
        this.setState({dropoffConfirmButton:false});
        this.map.setZoom(11);
        this.dropMarker.setMap(null);
        google.maps.event.clearListeners(this.map, 'center_changed');

        this.dropMarker = new google.maps.Marker   ({
            map: this.map,
            animation: google.maps.Animation.DROP,
            position: this.state.drop,
            draggable: true
        });
        if(this.pickMarker){
            this.pickMarker.setVisible(true);
        }

        google.maps.event.addListener(this.dropMarker, 'dragend', () =>{
            this.dropoffMarkerDragListener();

        });
        this.dropMarker.addListener('click', () =>{
            this.dropoffMarkerClickListener();
        });

        if (this.state.pick && this.state.drop){
            this.calculateRoute();
        }
    }

    //this function handle click event of Drop Marker
    dropoffMarkerClickListener=()=>{
        this.pickMarker.setVisible(false);
        this.directionsDisplay.set('directions', null);
        this.setState({dropoffConfirmButton:true});
        this.map.setCenter(this.dropMarker.getPosition());
        this.map.setZoom(16);
        this.map.addListener('center_changed',  () => {
            let lat=this.map.getCenter().lat();
            let lng=this.map.getCenter().lng();

            this.setState({drop:{lat:lat,lng:lng}},function () {
                let geocoder = new google.maps.Geocoder;
                geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
                    if (status === 'OK') {
                        document.getElementById('drop').value = results[0].formatted_address;
                    }
                });
            });
            this.dropMarker.setPosition({lat:lat,lng:lng});
            console.log(this.map.getCenter().lat(),this.map.getCenter().lng(),this.dropMarker.getPosition())

        });
    }

    //This function Handle drage event of drop marker
    dropoffMarkerDragListener= () => {
        let lat=this.dropMarker.getPosition().lat();
        let lng=this.dropMarker.getPosition().lng();

        this.setState({drop:{lat:lat,lng:lng}},function () {
            let geocoder = new google.maps.Geocoder;
            geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
                if (status === 'OK') {
                    document.getElementById('drop').value = results[0].formatted_address;
                }
            })
            console.log(this.state.drop);
        })
        if ((this.state.pick && this.state.drop) && (this.state.pickupConfirmButton === false && this.state.dropoffConfirmButton ===false)){
            this.calculateRoute();
        }
    };

    //this function set direction and calculate the root of pick and drop
    calculateRoute = () =>{
        var request ={
            origin:this.state.pick,
            destination:this.state.drop,
            travelMode:"DRIVING"
        };
        this.directionsService.route(request,(result,status) => {
            if(status== "OK"){
                console.log(result.routes[0].legs[0].distance);
                this.props.routeCalc(result.routes[0].legs[0].distance);
                this.directionsDisplay.setDirections(result);
            }
        });
    };


    render(){

        return(
            <div className="Map" ref={node => this.focus = node}>

                    <Alert
                        message="Tap or Drag Marker[s] to set exact location Then Click on Confirm Location"
                        type="info"
                        showIcon
                    />
                    <div id="map" style={{height: "500px"}}></div>
                    {this.state.pickupConfirmButton && <Button  className="cnfrmBtn"  size="large" onClick={this.pickupMaker}>Confirm Location</Button> }
                    {this.state.dropoffConfirmButton && <Button className="cnfrmBtn" size="large" onClick={this.dropoffMaker}>Confirm Location</Button> }

            </div>
        )
    }
}

function mapStateToProps (state) {
    return {pickupProps:state.BookingData.pickup}
}
// export default Map;
const ScriptLoadedMap = scriptLoader(
    [config.MapApi]
)(Map);
export default connect(mapStateToProps,actions)(ScriptLoadedMap);

i'm sending false value from Booking to action creator then i'm dispatching and storing value in action in reducer

but when i'm calling pickupProps from Map component first time i'm getting undefined after first time getting false value.
so here my problem is how can i get first time (asynchronous) false value when it called from Booking component.

来源:https://stackoverflow.com/questions/50406252/first-time-getting-undefined-props-from-mapstatetoprops

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!