I have two sliders, each with an event listener. Using your mouse to adjust one slider should update a shared state, which should then cause a change in the second slider. However, I only want the event listener for the first slider to fire. In the code I have below, the second slider's event listener is also firing, as can be seen by console prints of the form "Slider y was dragged..." when dragging the first slider. Is there some way to filter out the second slider's event listener firing?
function MySlider(props) {
const sliderRef = useRef();
useEffect(() => {
const slider = sliderRef.current;
const onChange = (evt) => {
const v = evt.detail.value;
console.log("Slider " + props.name + " was dragged to: " + v);
props.update(v);
}
slider?.addEventListener('change', onChange);
return () => {
slider?.removeEventListener('change', onChange);
}
}, []);
return (
<toolcool-range-slider
id={props.name}
min={props.min}
max={props.max}
value={props.value}
step="1"
ref={sliderRef}
/>
);
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
x: 10,
y: 5,
};
}
updateX(x) {
this.setState({
x: x,
y: Math.ceil(x/2),
});
}
updateY(y) {
this.setState({y: y});
}
render() {
const x = this.state.x;
const y = this.state.y;
const minY = Math.ceil(x/2);
const maxY = x;
return (
<div>
<table><tbody>
<tr>
<td>Choose x:</td>
<td style=>
<MySlider name="x" min={10} max={50}
value={this.state.x}
update={(x) => this.updateX(x) }
/>
</td>
<td>{x}</td>
</tr>
<tr>
<td>Choose a y in the range [x/2, x]:</td>
<td style=>
<MySlider name="y" min={minY} max={maxY}
value={this.state.y}
update={(y) => this.updateY(y) }
/>
</td>
<td>{y}</td>
</tr>
</tbody></table>
</div>
);
}
}
export default App;
The above example uses the toolcool-range-slider library, but I am fine using any slider implementation.
from React: multiple sliders sharing a common state
No comments:
Post a Comment