I have a range input with a react component, it’s only moving the slider. not triggering the callback function that’s there onChange
Trigering event explicitly isnt working either for react.
const volumeResetHandler = async () => {
document.querySelector('input[type=range]').value = 0;//as mentioned by @mathias-s setSlv(0) should also be fine , my concern is the next line
document.querySelector('input[type=range]').dispatchEvent(new Event("change"));
}
<input
className="slider_input"
type="range"
value={slv}
min="0"
max="600"
step="10"
autoFocus
onChange={volumeChangeHandler}
/>
<h3 onClick={volumeResetHandler} className="cursor-pointer">Reset</h3>
I was expecting volumeChangeHandler
would get triggered on document.querySelector('input[type=range]').value = 0;
but it doesn’t
All solutions mentioned here suffers from same issue
this does for jquery, without looking at react or javscript,
it doesnt answer as it is for jquery , changing jquery to js like this in react isn’t working
either.
So there must be something different going on with events in react.
Here is the updated code after trying useRef
(as suggested by @LãNgọcHải)
import { useRef } from 'preact/hooks'
const inputRef = useRef<HTMLInputElement>(null)
const volumeResetHandler = async () => {
inputRef.current.value = 0
}
<input
className="slider_input"
type="range"
value={slv}
min="0"
max="600"
step="10"
autoFocus
onChange={volumeChangeHandler}
ref={inputRef}
/>
<h3 onClick={volumeResetHandler} className="cursor-pointer">Reset</h3>
Inspiration from this
2
Answers
I got it working with @LãNgọcHải 's code:
Thanks a lot @LãNgọcHải . Only a small issue I have is I had a logic on
event.isTrusted==true
which is nowfalse
for explicitly triggering event. I would have to find some work around for that. I guess that's whatbubbles
is for ?In React, you need to use a controlled input to solve this. You should avoid using DOM manipulations like
querySelector
in combination with React for cases like this.To render a controlled input, pass the
value
prop to it. React will force the input to always have the value you passed.Use the
onChange
prop to callsetValue
to ensure that the input value always reflects the React state.You can also call
setValue
from other buttons or elements, like this:If you have more logic in your
volumeChangeHandler
, that should be run for bothvolumeChangeHandler
andvolumeResetHandler
, the idiomatic way to solve this in React would be to move that custom logic into its own function like this: