In following example, how can I disable the button during a geolocation request? In this.props.inProgress isn't set on init, I would like to disable button when getCurrentPosition is requested and enable if RECEIVE_LOCATION is resolved. What is correct approach? Do I to use state and copy props to the GeoButton?
export function getGeolocation() {
return dispatch => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
dispatch({
type: 'RECEIVE_LOCATION',
coords: {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
inProgress: false,
},
});
});
}
}
}
export function geolocation(state={}, action) {
switch (action.type) {
case 'RECEIVE_LOCATION':
var newState = action.coords;
return newState;
default:
return state;
}
}
class GeoButton extends React.Component {
constructor(props) {
super(props);
}
findLocation(e) {
e.preventDefault();
this.props.dispatch(getGeolocation());
}
render() {
console.log(this.props); // on init geolocation object is empty
var self = this;
return (
<div>
<button type="button" onClick={this.findLocation} disabled={self.props.geolocation.inProgress}>Get location</button>
</div>
)
}
}
export default connect(state => ({
geolocation: state.geolocation
}))(GeoButton); // just gives it dispatch()
To disable a button using only JavaScript you need to set its disabled property to false . For example: element. disabled = true . And to enable a button we would do the opposite by setting the disabled JavaScript property to false .
Use the disabled prop to disable a button in React, e.g. <button disabled={true}>Click</button> . You can use the prop to conditionally disable the button based on the value of an input field or another variable or to prevent multiple clicks to the button.
Button component can be enabled/disabled by giving disabled property. To disable Button component, the disabled property can be set as true .
You can enable or disable the ButtonGroup for Angular. By default, the component is enabled. To disable the whole group of buttons, set the disabled attribute of the ButtonGroup to true . To disable a specific button, set its own disabled attribute to true and leave the disabled attribute of the ButtonGroup undefined.
When doing async in redux, you often need to call dispatch twice. One synchronous, one asynchronous.
Your action should look something like this:
export function getGeolocation() {
return dispatch => {
dispatch({ type: 'FETCHING_LOCATION' });
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
dispatch({
type: 'RECEIVE_LOCATION',
coords: {
latitude: position.coords.latitude,
longitude: position.coords.longitude
}
});
});
}
};
}
And your reducer should look like this. I've tweaked the structure of the state object, to separate the app data from the ui data.
export function geolocation(state = {}, action) {
switch (action.type) {
case 'RECEIVE_LOCATION':
return {
coords: action.coords,
inProgress: false
};
case 'FETCHING_LOCATION':
return {
coords: null,
inProgress: true
};
}
return state;
}
There's no need to have the inProgress flag set within your action creator. The reducer can derive it from the action type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With