Reputation: 22148
I'm still new to Redux.
I want my app to manage a list of places. I have followed the Official TODOList tutorial and replaced TODO
s with Place
s. Good start :)
Now, I'd like to use the Geolocation API to automatically add the current user's place if available.
I have a <PlaceInput>
container, which when triggered dispatch
es the event addPlace
.
But I'm wondering where I should add the logic to add the current users' place.
let store = createStore(placesApp);
// update the store immediately if available
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
I'm not a big fan of this strategy since the authorization for geolocation requires user action the first time, which makes it asynchronous by nature.
class AddUserGeolocation extends React.Component {
static propTypes = {
alreadyAsked: React.PropTypes.bool.isRequired
}
componentDidMount {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
dispatcher(addPlace('You', position.coords.latitude, position.coords.longitude))
});
dispatcher(askedForUserLocation())
}
};
render() {
let result = this.props.alreadyAsked ? 'Asked' : 'Not yet'
return (
<div>
{result}
</div>
)
}
}
Upvotes: 3
Views: 874
Reputation: 1089
You can store this information in the Store. :D All the logic is handled inside your reducer. Something like this:
const initialState = {
places: [],
alreadyAsked: false
};
const placesReducer = (state = [], action) => {
switch(action.type) {
case 'ADD_PLACE':
return [...state, action.place];
default:
return state;
}
};
const askReducer = (state = false, action) => {
switch(action.type) {
case 'ASK':
return true;
default:
return state;
}
};
const appReducers = combineReducers({
places: placesReducer,
alreadyAsked: askReducer
});
let store = createStore(initialState, appReducers);
// update the store immediately if available
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
And
@connect(
state => ({
places: state.places,
alreadyAsked: state.alreadyAsked
}),
dispatcher => ({
addPlace: (who, lat, long) => ({ type: 'ADD_PLACE', {who, lat, long}}),
askedForUserLocation: () => ({ type: 'ASK' })
})
)
class AddUserGeolocation extends React.Component {
static propTypes = {
alreadyAsked: React.PropTypes.bool.isRequired
}
componentDidMount() {
const { addPlace, askedForUserLocation } = this.props
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
dispatcher(addPlace('You', position.coords.latitude, position.coords.longitude))
});
dispatcher(askedForUserLocation())
}
}
render() {
let result = this.props.alreadyAsked ? 'Asked' : 'Not yet'
return (
<div>
{result}
</div>
)
}
}
Upvotes: 1