Reputation: 23811
I want to fire an event onDragStop
rather than onChange
using a Material UI Slider
in my React app (so that the event fires fewer times). However, the documentation indicates that the onDragStop
function signature only has the mouseevent: function(event: object) => void
. So, the following works with onChange
:
<Slider onChange={ (e, val) => this.props.update(e, control.id, val) } />
However, this event doesn't have a second parameter val
:
<Slider onDragStop={ (e, val) => this.props.update(e, control.id, val) } />
How can I get the current value of the Slider in the onDragStop
function? Note, I'm unable to use this
, as it refers to the parent component.
Upvotes: 22
Views: 30358
Reputation: 1
You can use input onBlur
Event:
<Slider
value={value}
onChange={handleChange}
slotProps={{
input: {
onBlur: () => {
console.log("run heavy save here");
},
},
}}
/>
Upvotes: 0
Reputation: 1
import React, { useState } from 'react';
import Slider from '@mui/material/Slider';
function YourComponent() {
// Set an initial value for maxDistance
const [maxDistance, setMaxDistance] = useState(/* initial value */);
// Handle the Slider value change when the user commits to a value
const handleSliderChange = (event, value) => {
setMaxDistance(value);
};
return (
<div>
<label htmlFor="non-linear-slider">Max Distance:</label>
<Slider
defaultValue={maxDistance}
step={5}
onChangeCommitted={handleSliderChange}
valueLabelDisplay="auto"
aria-labelledby="non-linear-slider"
/>
<p>Current Max Distance: {maxDistance}</p>
</div>
);
}
export default YourComponent;
//use this Example using the onChangeCommitted ,it will work
Upvotes: 0
Reputation: 41
I know this is super late, but I wanted to add my two cents:
If all you need is to not constantly fire an event, you can use debouncing like this:
const handleSliderChange = useCallback((event, value) => {
debounceSliderChange(value);
}, []);
const debounceSliderChange = debounce((val) => {
setValue(val)
}, 200);
and then:
<Slider onChange={(e, v) => handleSliderChange(e, v)}/>
For reference, I am importing debounce from: "@mui/material/utils"
https://codesandbox.io/s/festive-dirac-fij37p?file=/src/App.js
Upvotes: 4
Reputation: 81350
<Slider
// invoked when the user drags the thumb
onChange={(_, newValue) => update(newValue)}
// invoked when the user drops the thumb
onChangeCommitted={(_, newValue) => update(newValue)}
/>
Upvotes: 9
Reputation: 1069
In a newer version of Material UI you could use:
<Slider
onChange={} // for example updating a state value
onChangeCommitted={} // for example fetching new data
/>
Upvotes: 36
Reputation: 3967
If you want the Slider
value to be part of the component state, e.g. for triggering a re-render of the Slider
when it changes (this requires you to pass this.state.value
to the Slider
as well), you can do this:
class Parent extends Component {
render() {
return <Slider value={this.state.value} onChange={this.handleChange} onDragStop={this.handleDragStop}/>
}
handleChange = (event, value) => this.setState({ value });
handleDragStop = () => this.props.update(this.state.value);
}
Otherwise you can just assign the value to this
:
class Parent extends Component {
render() {
return <Slider onChange={this.handleChange} onDragStop={this.handleDragStop}/>
}
handleChange = (event, value) => this.value = value;
handleDragStop = () => this.props.update(this.value);
}
Upvotes: 4
Reputation: 186
Also ran into this problem! If you use a component inside a class, use both callbacks:
<Slider onChange={ (e, val) => this.val = val }
onDragStop={ (e) => this.props.update(e, control.id, this.val)
/>
Upvotes: 17