FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Building an OpenLayers 3 map viewer with React @PirminKalberer - - PowerPoint PPT Presentation
Building an OpenLayers 3 map viewer with React @PirminKalberer - - PowerPoint PPT Presentation
FOSS4G 2015 Building an OpenLayers 3 map viewer with React @PirminKalberer Sourcepole AG, Switzerland www.sourcepole.com FOSS4G Seoul 17.9.15 OpenLayers 3 + React About Sourcepole > QGIS > Core dev. & Project Steering Commitee >
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
About Sourcepole
> QGIS
> Core dev. & Project Steering Commitee > QGIS Server, Printing, Plugins, … > QGIS Enterprise > QGIS Cloud
> OGR / GDAL
> Interlis drivers > Schema support for PostGIS driver
> Web-GIS
> Mapfish Committer / Mapfish Appserver > Contributions to MapServer, Openlayers, ...
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Map/Table Example
> https://github.com/pka/ol3-react-example
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
The „JQuery way“
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
The „JQuery way“ more complex
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
The MVC way
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
The MVC way – more complex
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
The React way
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
React
> http://facebook.github.io/react/ > The V in MVC > Components, not templates
> Display logic and markup are thighly coupled
> Re-render, don't mutate the DOM > Fast Virtual DOM > Components are reusable, composable, unit testable > Concepts: https://youtu.be/x7cQ3mrcKaY
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
React Component
var MyComponent = React.createClass({ render: function(){ return ( <h1>Hello {this.props.name}!</h1> ); } }); React.render(<MyComponent name="World" />, document.getElementById('myDiv'));
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
JSX
> JSX:
render () { return ( <h1>Hello {this.props.name}!</h1> );
> Javascript:
render () { return React.createElement("div", null, "Hello ", this.props.name); }
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Lists and events
var PlaceList = React.createClass( { render: function() { var placeNodes = this.props.places.map(function (place) { return ( <li onClick={onSelectClick}>{place}</li>; }; return ( <ul> {placeNodes} </ul> ); } });
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Composing components
> CommentBox > CommentList > Comment > CommentForm
var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> <CommentForm /> </div> ); } });
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Props / State
> Props
> Read-only attributes
> State
> State is set using the setState method. Calling setState triggers UI updates.
> Re-render the whole app once the state changes > Unidirectional Data Flow > Data is guaranteed up to date > Virtual DOM: makes re-rendering on every change fast
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Virtual DOM
> On every update React builds a new virtual DOM subtree > … diffs it with the old one > … computes the minimal set of DOM mutations and puts them in a queue > … and batch executes all updates
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Redux
> Flux: application architecture
> Pattern rather than framework > Unidirectional data flow > http://facebook.github.io/flux/
> Redux: “Reduced” Flux implementation
> http://rackt.github.io/redux/
> Single store > Central state State history, etc. → > Middleware (Logging, etc.)
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
React with OpenLayers
> HTML:
<body> <div id="olmap"/> <div id="reactcomponents"/> </body>
> React state:
> visible places > selected place
> React component:
var PlaceList = React.createClass( { render: function() { return (
<ul>{...}</ul> );
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Updating state
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Updating State
> OL React State →
function updateVisiblePlaces() { var visiblePlaces = placeLayer.getSource().getFeaturesInExtent(extent) ... store.dispatch(visiblePlacesAction(visiblePlaces)) } placeLayer.on('change', updateVisiblePlaces);
> React Component State + OL update →
- nSelectClick: function(e) {
dispatch(selectAction(itemId)); // Update map updateSelection(itemId) }
> Alternative approach: use Redux middleware for updating state in OL
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Hot reloading
> Presentation at ReactEurope 2015: https://youtu.be/xsSnOQynTHs > Save change in source (JS, CSS, …) → Updated view in browser
> Keeps application state > State history: Undo/Redo > State snapshots for unit testing
FOSS4G Seoul 17.9.15 OpenLayers 3 + React
Complete code example
> https://github.com/pka/ol3-react-example
FOSS4G Seoul 17.9.15 OpenLayers 3 + React