I am working in React Hooks and have encountered a problem with the useContext method. My context class for a MapStyle (using Google Maps API) is as follows:
import React, { createContext, useState } from 'react';
const MapStyleContext = createContext();
function MapStyleProvider(props) {
const [selectedMapStyle, setSelectedMapStyle] = useState();
return (
<MapStyleContext.Provider value={{ selectedMapStyle, setSelectedMapStyle}}>
{props.children}
</MapStyleContext.Provider>
);
}
export { MapStyleContext, MapStyleProvider };
I have the map component attempting to access the selectedMapStyle property:
...
export default function Map() {
const { isLoaded, loadError } = useLoadScript({
googleMapsApiKey: process.env.REACT_APP_MAPS_API_KEY
});
const { selectedMapStyle } = useContext(MapStyleContext);
...
Finally, in the MapStyle component, I am attempted to use the setter setSelectedMapStyle whenever the user changes the value of the radio button:
import React, { useContext } from 'react';
import { Card, CardBody, Button, FormGroup, Label, Input } from 'reactstrap';
import { MenuContext } from '../../MenuContext';
import { MapStyleContext } from '../mapStyle/MapStyleContext'
import '../Tool.css';
export default function MapStyle() {
const {setSelectedItem} = useContext(MenuContext);
const {setSelectedMapStyle} = useContext(MapStyleContext);
const mapStyles = [
{ 'label': 'Map (default)', 'value': 'default' },
{ 'label': 'Grayscale (Clean)', 'value': 'cleanGray' },
{ 'label': 'Subtle Grayscale', 'value': 'subtleGray' },
{ 'label': 'Ultra light', 'value': 'ultralight' },
{ 'label': 'Clean (no labels)', 'value': 'cleanNoLabel' },
{ 'label': 'Clean (roads)', 'value': 'cleanRoads' }
];
return (
<div className="tool">
<Card>
<CardBody>
<div className="clearfix">
<h3 className="float-left mb-0 mr-2">Map Style</h3>
<Button onClick={() => setSelectedItem(null)} className="float-right" close />
</div>
<hr />
<FormGroup tag="fieldset">
{mapStyles.map(mapStyle => (
<FormGroup key={mapStyle.value} check>
<Label check>
<Input type='radio' name='mapStyle' value={mapStyle.value} onChange={setSelectedMapStyle(mapStyle.value)}/>
{mapStyle.label}
</Label>
</FormGroup>
))}
</FormGroup>
</CardBody>
</Card>
</div>
);
}
I am not quite sure where I am going wrong, but the context props never seem to load in correctly (giving me the type error) when I use this context.
The problem you've faced here is that the value of the
useContext(MapStyleContext)
is null as of initialisation and you've never wrapped the parent component or the current component inside theContext.Provider
.Here is an example: