Get Material UI Slider value in onDragStop event
Asked Answered
W

6

22

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.

Winglet answered 22/11, 2017 at 16:51 Comment(0)
H
17

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)
/>
Hydrops answered 1/12, 2017 at 7:42 Comment(0)
T
36

In a newer version of Material UI you could use:

<Slider
  onChange={} // for example updating a state value
  onChangeCommitted={} // for example fetching new data
/>
Teresetereshkova answered 23/4, 2020 at 12:55 Comment(1)
This answer is the new best answer.Inspire
H
17

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)
/>
Hydrops answered 1/12, 2017 at 7:42 Comment(0)
L
9
<Slider
  // invoked when the user drags the thumb
  onChange={(_, newValue) => update(newValue)}
  // invoked when the user drops the thumb
  onChangeCommitted={(_, newValue) => update(newValue)}
/>

Live Demo

Codesandbox Demo

Lombardo answered 8/11, 2021 at 9:0 Comment(0)
U
4

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);
}
Union answered 29/12, 2017 at 12:51 Comment(0)
V
4

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"

Demo:

https://codesandbox.io/s/festive-dirac-fij37p?file=/src/App.js

Visualize answered 25/7, 2022 at 12:24 Comment(0)
S
0
    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
Slew answered 24/12, 2023 at 2:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.