Short story: I am making my own GIS (geographic information system) and want to be able to upload JSON files with geographical data. I do not however want to save files in a database, just in a list. Furthermore I’m using Context to send data to the (leaflet) component. When I upload new JSONs to the layerList it gets updated but the component does not re-render. I have console logged the list after uploading files and the all get added.
The use of context is based off of DevEd’s guide on context from youtube https://www.youtube.com/watch?v=35lXWvCuM8o&t=1352s
Here is my code
Context:
import React, {createContext, useState, useEffect} from 'react'; import "../../App.css"; export const FileContext = createContext() export const FileProvider = (props) => { const [layerList, setLayerList] = useState(''); return( <FileContext.Provider value = {[layerList, setLayerList]}> {props.children} </FileContext.Provider> ); }
Upload component:
import React, {createContext, useContext, useState} from 'react'; import "../../App.css"; import {FileContext} from './FileContext' function FileUpload() { const [layerList, setLayerList] = useContext(FileContext) const onFileChange = e => { const fileReader = new FileReader(); fileReader.readAsText(e.target.files[0], "UTF-8"); fileReader.onload = e => { setLayerList(prevLayer => [...prevLayer, JSON.parse(e.target.result)]); }; } return ( <div> <div id='fileupload'> <input type="file" onChange={onFileChange} /> </div> </div> ); } export default FileUpload;
Map:
import React, { useContext } from 'react'; import { Map, TileLayer, GeoJSON} from 'react-leaflet' import "../App.css"; import { FileContext } from '../LandingPage/ToolbarComponents/FileContext'; import data from '../Layers/layer1.json' import data1 from '../Layers/layer2.json' function MapOslo() { const [layerList] = useContext(FileContext) return ( <Map center={[59.93, 10.75]} zoom={1}> <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' /> <GeoJSON data={layerList} style={['color','#006400']} /> </Map> ); } export default MapOslo;
Advertisement
Answer
EDIT: I pulled your repo and I think it’s solved now. Notice how the map.js component it’s logging the data from the updated .json file. Your map.js component should look like the following:
import React, { useContext, useEffect, useState} from 'react'; import { Map, TileLayer, GeoJSON} from 'react-leaflet' import "../App.css"; import { FileContext } from ../LandingPage/ToolbarComponents/FileContext'; import data from '../Layers/layer1.json' import data1 from '../Layers/layer2.json' function MapOslo() { const [layerList] = useContext(FileContext); const [layerState, setLayerState] = useState(layerList); useEffect(() => { setLayerState(layerList); console.log(layerState); }); return ( <Map center={[59.93, 10.75]} zoom={1}> <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' /> <GeoJSON data={layerState} style={['color','#006400']} /> </Map> ); } export default MapOslo;
EDIT 2: I’m not sure what do you mean by the layers… but it’s showing the marker now with the static position you previously included in there. See below updated map.js:
import React, { useContext, useEffect, useState} from 'react'; import { Map, TileLayer, GeoJSON, Marker, Popup} from 'react-leaflet' import "../App.css"; import { FileContext } from '../LandingPage/ToolbarComponents/FileContext'; import data from '../Layers/layer1.json' import data1 from '../Layers/layer2.json' function MapOslo() { const [layerList] = useContext(FileContext); const [layerState, setLayerState] = useState(layerList); useEffect(() => { setLayerState(layerList); console.log(layerState); }); const position = [59.93, 10.75]; return ( <Map center={position} zoom={6}> <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' /> <GeoJSON data={layerState} style={['color','#006400']} /> <Marker position={position}> <Popup>A pretty CSS3 popup.<br />Easily customizable.</Popup> </Marker> </Map> ); } export default MapOslo;