[material-ui][Slider] Sometimes the value in onChange and the value in onChangeCommitted are output differently
Steps to reproduce
Steps:
- Do a lot of drag on the slider from side to side and then stop dragging.
Current behavior
Sometimes the value in onChange and the value in onChangeCommitted are not the same.
https://github.com/mui/material-ui/assets/57526248/e978d052-dae4-448e-bfa2-4cbc486a67f7
Expected behavior
The value in onChange and the value in onChangeCommitted must be the same
Context
No response
Your environment
OS: Windows 10 10.0.19045 @emotion/react: ^11.11.4 => 11.11.4 @emotion/styled: ^11.11.5 => 11.11.5 @mui/base: 5.0.0-beta.40 @mui/core-downloads-tracker: 5.15.14 @mui/material: ^5.15.14 => 5.15.14 @mui/private-theming: 5.15.14 @mui/styled-engine: 5.15.14 @mui/system: 5.15.14 @mui/types: 7.2.14 @mui/utils: 5.15.14 @types/react: 18.2.73 react: ^18.2.0 => 18.2.0 react-dom: ^18.2.0 => 18.2.0 typescript: 4.9.5
Search keywords: [Material-ui][Slider]
Thank you for your hard work. Please update the progress.
Seems like a bug. It's possible that the mouseup event, where the onChangeCommitted callback is triggered, occurs after the change event or keydown event, where the onChange callback is fired, resulting in the occasional difference in value.
Also, why do you expect it to be the same though? Do you have any use case?
I think the value should be the same because I get the value of onChange and the value of onChangeCommitted in the same slide action. Also, the value of onChangeCommitted is used to use the value at the end of the drag, and onChange is used to show the value when dragging on the screen. If it can be modified, by when can you do it?
Also, the value of onChangeCommitted is used to use the value at the end of the drag, and onChange is used to show the value when dragging on the screen.
I'm not sure how this is impacting you if they're different. It could be due to the order of user events, as mentioned earlier. I am not sure whether to mark it as a bug or not. CC @mnajdova @DiegoAndai
If it can be modified, by when can you do it?
This is open for community contributions if it's a bug. You're welcome to create a pull request. Just keep in mind that this adjustment needs to be made in the useSlider hook within the Base UI repository at https://github.com/mui/base-ui.
Hey @Jeon-MinGyu, thanks for the report! Could you share the code in your video as a minimal reproduction? This would help a lot. A live example would be perfect. This StackBlitz sandbox template may be a good starting point. I'm also curious about what's your use case in which this difference is relevant.
I agree with @ZeeshanTamboli that this is probably an edge case in the order of user events.
I am not sure whether to mark it as a bug or not.
Let's wait for the reproduction so we can test it with different browsers and CPU throttling. I would also like to test it with discrete sliders. I would say it's probably an enhancement unless it's really easy to repro, in which case it might be a bug.
@DiegoAndai, I will share the code you requested at the bottom. The use case of this is to provide only the value of the location on the screen when dragging in the thermostatic UI, and to set the temperature to the value of the location only when dragging is finished.
import * as React from 'react';
import Box from '@mui/material/Box';
import Slider from '@mui/material/Slider';
import {useState} from "react";
export default function App() {
const [slideValue, setSlideValue] = useState()
const [newSlideValue, setNewSlideValue] = useState()
function valuetext(value) {
setSlideValue(value)
return `${value}°C`;
}
function handleChangeSlider(){
setNewSlideValue(slideValue)
}
function onSlideChange(){
console.log('onChange Value' + slideValue)
}
return (
<div style={{ width : '100%', paddingTop : '80px'}}>
<Box sx={{ width: '50%', margin: 'auto' }}>
<Slider
aria-label="Always visible"
defaultValue={80}
getAriaValueText={valuetext}
step={1}
valueLabelDisplay="on"
onChangeCommitted={handleChangeSlider}
onChange={onSlideChange}
/>
<div style={{fontSize: '25px', marginTop: '60px'}}>{"onChange Slider Value : " + slideValue}</div>
<div style={{fontSize: '25px', marginTop: '20px'}}>{"onChangeCommitted Value : " + newSlideValue}</div>
</Box>
</div>
);
}
Also, when dragging for a short time in an IOS environment, it often returns to the value before dragging. The device used is iPhone X and the IOS version is 16.6.
https://github.com/mui/material-ui/assets/57526248/797f85e1-1de2-4e39-92bd-69763381903c
Can you tell me when this issue will be fixed?
I tested it and can confirm that it's easy to reproduce. This is on 4x slowdown throttle:
https://github.com/mui/material-ui/assets/16889233/a6050998-7619-4569-96fe-b7f4988e8122
I'm labeling this as a bug and adding the ready to take label. If anyone is interested, feel free to work on it. IF you want this issue fixed, please upvote it by adding a 👍🏼 (thumbs up) reaction to the description.
@DiegoAndai Can you tell me when this issue will be fixed?
Hey @Jeon-MinGyu, this issue is "waiting for upvotes", so at the moment there's no estimated time. I suggest the following:
- Anyone that needs this fix, please add an upvote (👍🏼 emoji) on this issue's description so we can track interest
- If anyone has the time and wants to try and fix it, you're more than welcome and we are happy to provide guidance
In case no one takes this, we might add it to the roadmap if it has enough upvotes, but there's no certainty at the moment.
I don't see any issue with the Slider component.
When we call a set state dispatcher, it may not update the state right away. In onChangeCommitted callback, we cannot assume that slideValue state has already updated and contains the newest value. The correct value is always passed as the second argument in the onChangeCommitted callback. Check the api for reference.
onChangeCommitted might be used like this:
import Slider from '@mui/material/Slider';
import {useState} from "react";
export default function App() {
const [slideValue, setSlideValue] = useState();
const [newSlideValue, setNewSlideValue] = useState();
return (
<div style={{ width : '100%', paddingTop : '80px'}}>
<Slider
defaultValue={30}
onChange={e => setSlideValue(e.target.value)}
onChangeCommitted={(e, v) => setNewSlideValue(v)}
/>
<div style={{fontSize: '25px', marginTop: '60px'}}>{"onChange Slider Value : " + slideValue}</div>
<div style={{fontSize: '25px', marginTop: '20px'}}>{"onChangeCommitted Value : " + newSlideValue}</div>
</div>
);
};
This issue is sometimes reproduced.
@mwashief The issue is that onChangeCommitted should match the last dispatched onChange, and this is not always the case. Here's the issue presenting itself when running the code you shared:
https://github.com/mui/material-ui/assets/16889233/29b23d4c-6a5e-4aec-8700-33acaa066386
This didn't even require throttling.
@DiegoAndai, interesting! I wasn't able to reproduce the issue using the code I shared. Check out this sandbox.
Could you double check, if you actually ran my code?
I tried to fix this issue, but I can't reproduce it. Does anyone know how to reproduce it stably?
This issue is not reproduced in the sandbox. It happened frequently when I checked with Ios after code execution.
I am also facing the same issue (the one where the values become similar to the one when dragging started)
The easiest way to reproduce for me is:
- ios > safari (simulator or device)
- dragging from a small value to a big one (ie: 10>50>100) or the other way around (100>50>10) and NOT small>big>small
I have also reproduced here, using the sliders at "Sizes": https://mui.com/material-ui/react-slider/
Now testing with a more powerful computer, it's harder to reproduce. But I was able to reproduce on @mwashief's sandbox on 6x CPU throttle:
https://github.com/mui/material-ui/assets/16889233/be31272f-37bf-418d-8d8f-723365bcf9ca
With a more powerful computer, it isn't as big of a problem. Seems like going outside of the boundaries is a way to trigger it easier.
Can this issue be fixed? If it is fixed, when will it be possible?
@Jeon-MinGyu, please upvote the issue if you wish this to land. I can't provide an expected timeline at this moment; I'm sorry.
Also, if anyone wants to work on it right now, please go ahead. I would be more than happy to guide it.
@DiegoAndai , I'd like to know how many upvotes to need for the issue this to land. I need a modification schedule for this issue
I'd like to know how many upvotes to need for the issue this to land
I have no answer to that. We pick what issues to work on by picking the most upvoted ones, so there's no exact number.
If you need this urgently, I encourage you to look into it and open a PR. I would be happy to guide you.