正在分派动作,但状态未更新

时间:2020-07-09 05:12:12

标签: javascript reactjs redux

我正在使用react-map-gl开发一个简单的地图应用。我在其他地方有一些onClick事件,但是地图上的事件却无法正常工作。具体来说,我的模态没有渲染。

我的情态动作:

import {TOGGLE_PROFILE, TOGGLE_MAP, TOGGLE_LOCATION} from './modalTypes';

export const toggleProfile = () => {
    return {
        type: TOGGLE_PROFILE
    }
}

export const toggleMap = (lat, lng) => {
    return {
        type: TOGGLE_MAP,
        payload: {
            latitude: lat,
            longitude: lng
        }
    }
}

export const toggleLocation = (id) => {
    return {
        type: TOGGLE_LOCATION,
        payload: {
            locationId: id
        }
    }
}

我的模态减速器

import {TOGGLE_PROFILE, TOGGLE_MAP, TOGGLE_LOCATION} from './modalTypes';

const initialState = {
    profileOpen: false,
    mapOpen: false,
    longitude: '',
    latitude: '',
    locationOpen: false,
    locationId: ''
}

const modalReducer = (state = initialState, action) => {
    switch(action.type){
        case TOGGLE_PROFILE:
            return {
                ...state,
                profileOpen: !state.profileOpen
            }
        case TOGGLE_MAP:
            return {
                ...state,
                mapOpen: !state.mapOpen,
                longitude: state.mapOpen === true ? '' : action.payload.longitude, 
                latitude: state.mapOpen === true ? '' : action.payload.latitude
            }
        case TOGGLE_LOCATION:
            return {
                ...state,
                locationOpen: !state.locationOpen,
                locationId: action.payload.locationId
            }
        default:
            return state;
    }
}

export default modalReducer;

然后我有三个模态。 toggleProfile可以完美运行,但是toggleMap会更新状态,即使已检测到单击,toggleLocation甚至都不会检测到调度动作。

我要如何开始调试它并找出问题所在?

编辑以添加进行调用的组件,很抱歉,如果调用时间太长,我可以公开发布到其他地方:

import React, { useEffect } from 'react'
import {connect} from 'react-redux';
import {getUserLocation, updateMap, getLocationsRequest, getUser, toggleMap, toggleLocation} from '../../redux';
import './mapPage.scss';
import 'mapbox-gl/dist/mapbox-gl.css';
import ReactMapGL, {Marker} from 'react-map-gl';
import {useHistory} from 'react-router-dom';
import NavBar from '../NavBar/NavBar';
import ProfileModal from '../ProfileModal/ProfileModal';
import MapModal from '../MapModal/MapModal';
import LocationModal from '../LocationModal/LocationModal';

function MapPage({viewport, getUserLocation, updateMap, getLocations, locations, getUser, toggleMap}) {

    const history = useHistory();

    // Using hooks to get the user and their location, because what do we say to class components and componentDidMount? NOT TODAY!
    useEffect(() => {
        if(localStorage.token){
            getUser(localStorage.token);
            navigator.geolocation.getCurrentPosition(coords => {
                getUserLocation(coords.coords.latitude, coords.coords.longitude);
                getLocations(coords.coords.latitude, coords.coords.longitude);
            });
        } else {
            history.push('/');
        }
    }, [getUserLocation, getLocations, getUser, history]);

    // When the user drags the map, the coordinates are updated in the state and the map gets redrawn.
    const onViewportChange = (viewport) => {
        updateMap(viewport);
        getLocations(viewport.latitude, viewport.longitude);
        getMarkers();
    }

    // When the user drags the map into an area with reviews, markers are pulled to show how many reviews each location has.
    const getMarkers = () =>{
        return locations.map(location => {
            return (
                <Marker key={location.id} offsetLeft={-25} offsetTop={-70} latitude={parseFloat(location.lat)} longitude={parseFloat(location.lng)}>
                    <div className="marker-styles" onClick={() =>locationClickHandler(location.id)} >
                        <p>{location.review_count}</p>
                    </div>
                </Marker>
            );
        });
    }

    const locationClickHandler = id => {
        toggleLocation(id);
    }

    // When the user clicks on the map, open a modal for creating a new location with review
    const mapClickHandler = (info) => {
        toggleMap(info.lngLat[1], info.lngLat[0]);
    }

    // Importing Mapbox's API key from my environment variables.
    const TOKEN = process.env.REACT_APP_TOKEN;

    // This is the map component with its corresponding options.
    return (
        <>
            <LocationModal />
            <NavBar />
            <ReactMapGL 
            {...viewport}
            className={"map-container"}
            onClick={(info) => mapClickHandler(info)}
            attributionControl={false}
            onViewportChange={(viewport) => onViewportChange(viewport)}
            mapStyle="mapbox://styles/mapbox/streets-v10"
            mapboxApiAccessToken={TOKEN}>
            {getMarkers()}
            </ReactMapGL>
            <ProfileModal />
            <MapModal />
        </>
    )
}


// Bringing the state from redux...
const mapStateToProps = (state) => {
    return {
        viewport: state.viewport,
        locations: state.locations
    };
};

// ...as well as some actions...
const mapDispatchToProps = dispatch => {
    return {
        getUserLocation: (lat, lng) => dispatch(getUserLocation(lat, lng)),
        updateMap: (viewport) => dispatch(updateMap(viewport)),
        getLocations: (lat, lng) => dispatch(getLocationsRequest(lat, lng)),
        getUser: (token) => dispatch(getUser(token)),
        toggleMap: (lat, lng) => dispatch(toggleMap(lat, lng)),
        toggleLocation: (id) => dispatch(toggleLocation(id))
    }
}

// ...and finally sending them back to the component as props.
export default connect(mapStateToProps, mapDispatchToProps)(MapPage);

0 个答案:

没有答案