Created
April 7, 2017 15:27
-
-
Save hellobrian/e7cf42e5b97d439afb7590cd62609eb5 to your computer and use it in GitHub Desktop.
React Training: Render Props
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////////////////////////////////////// | |
// Exercise: | |
// | |
// - Refactor App by creating a new component named `<GeoPosition>` | |
// - <GeoPosition> should use a child render callback that passes | |
// to <App> the latitude and longitude state | |
// - When you're done, <App> should no longer have anything but | |
// a render method | |
// | |
// Got extra time? | |
// | |
// - Now create a <GeoAddress> component that also uses a render | |
// callback with the current address. You will use | |
// `getAddressFromCoords(latitude, longitude)` to get the | |
// address, it returns a promise. | |
// - You should be able to compose <GeoPosition> and <GeoAddress> | |
// beneath it to naturally compose both the UI and the state | |
// needed to render it | |
// - Make sure <GeoAddress> supports the user moving positions | |
import React, { PropTypes } from 'react' | |
import ReactDOM from 'react-dom' | |
import LoadingDots from './utils/LoadingDots' | |
import getAddressFromCoords from './utils/getAddressFromCoords' | |
class Geoposition extends React.Component { | |
static PropTypes = { | |
children: PropTypes.func, | |
} | |
state = { | |
coords: { | |
latitude: null, | |
longitude: null | |
}, | |
error: null | |
} | |
componentDidMount() { | |
this.geoId = navigator.geolocation.watchPosition( | |
(position) => { | |
this.setState({ | |
coords: { | |
latitude: position.coords.latitude, | |
longitude: position.coords.longitude | |
} | |
}) | |
}, | |
(error) => { | |
this.setState({ error }) | |
} | |
) | |
} | |
componentWillUnmount() { | |
navigator.geolocation.clearWatch(this.geoId) | |
} | |
render() { | |
return this.props.children(this.state.error, this.state.coords); | |
} | |
} | |
class App extends React.Component { | |
render() { | |
return ( | |
<div> | |
<h1>Geolocation</h1> | |
<Geoposition> | |
{(error, coords) => | |
(error) | |
? <div>Error: {error.message}</div> | |
: ( | |
<dl> | |
<dt>Latitude</dt> | |
<dd>{coords.latitude || <LoadingDots/>}</dd> | |
<dt>Longitude</dt> | |
<dd>{coords.longitude || <LoadingDots/>}</dd> | |
</dl> | |
) | |
} | |
</Geoposition> | |
</div> | |
) | |
} | |
} | |
ReactDOM.render(<App/>, document.getElementById('app')) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment