我有一个范围输入,发生了onChange
的一些情况。这与手动单击/拖动用法所期望的一样。但是,当我尝试使用JavaScript更改值时,我的onChange
事件似乎没有触发。
这是我的代码:
const App = () => {
const [currentValue, setCurrentValue] = useState(0);
const setRangeValue = () => {
const range = document.querySelector("input");
range.value = 50;
range.dispatchEvent(new Event("change", { bubbles: true }));
};
return (
<div className="App">
<h1>Current Value: {currentValue}</h1>
<input
type="range"
min={0}
max={100}
step={10}
onChange={e => {
console.log("Change!");
setCurrentValue(+e.target.value);
}}
defaultValue={0}
/>
<button onClick={setRangeValue}>Set current value to 50</button>
</div>
);
};
这在CodeSandbox中(不)起作用: https://codesandbox.io/s/divine-resonance-rps1n
注意:
仅作澄清。我的实际问题来自使用玩笑/反应测试库测试我的组件。按钮演示只是一种可视化问题的好方法,而无需费心重复所有测试内容。
const getMessage = (value, message) => {
const slider = getByRole('slider');
fireEvent.change(slider, { target: { value } });
slider.dispatchEvent(new Event('change', { bubbles: true }));
return getByText(message).innerHTML;
};
fireEvent更改值时,不会运行附加到输入的onChange
事件。这意味着getByText(message).innerHTML
是不正确的,因为这只会在设置挂钩称为onChange
时更新。 (当手动单击/拖动输入滑块时,所有这些都有效,我只是无法对其进行“测试”)
任何帮助都会很棒!
答案 0 :(得分:0)
问题在于React具有一个虚拟DOM,该虚拟DOM不直接连接到DOM。注意React中的事件是SyntheticEvents。它们不是来自DOM的实际事件。 https://github.com/facebook/react/issues/1152
如果这是用于单元测试,请为滑块和文本创建一个单独的组件,并确保它们与道具彼此独立地发挥预期的作用。
有关如何专门测试范围滑块的更深入的文章,请查看https://blog.bitsrc.io/build-and-test-sliders-with-react-hooks-38aaa9422772
祝你好运!