#javascript #reactjs #react-hooks #material-ui
Вопрос:
Я использую непрерывный слайдер из metrial-ui в проекте ReactJS. Я хочу управлять ползунком таким образом, чтобы при нажатии на кнопку воспроизведения ползунок начинал двигаться и останавливался при нажатии кнопки «Стоп». ниже приведен код ползунка.
const useStyles = makeStyles({
root: {
width: 200,
},
});
<div className={classes.root}>
<Typography id="continuous-slider" gutterBottom>
Volume
</Typography>
<Grid container spacing={2}>
<Grid item>
<VolumeDown />
</Grid>
<Grid item xs>
<Slider value={value} onChange={handleChange} aria-labelledby="continuous-slider" />
</Grid>
<Grid item>
<VolumeUp />
</Grid>
</Grid>
Заранее спасибо
Ответ №1:
Это можно сделать, позвонив setState
, чтобы обновить Slider
значение через определенный интервал. Вам нужно будет использовать useEffect
для создания и очистки интервального обратного вызова при изменении isRunning
состояния:
export default function ContinuousSlider() {
const [value, setValue] = useState<number>(30);
const [isRunning, setIsRunning] = useState(false);
const directionRef = useRef<"back" | "forward">("back");
const intervalIdRef = useRef(0);
const handleChange = (event: any, newValue: number | number[]) => {
setValue(newValue as number);
};
const handleBack = () => {
directionRef.current = "back";
if (!isRunning) {
setIsRunning(true);
}
};
const handleNext = () => {
directionRef.current = "forward";
if (!isRunning) {
setIsRunning(true);
}
};
const handleStop = () => {
setIsRunning((r) => !r);
};
useEffect(() => {
if (isRunning) {
intervalIdRef.current = setInterval(() => {
if (directionRef.current === "forward") {
setValue((v) => v);
}
if (directionRef.current === "back") {
setValue((v) => --v);
}
}, 16);
}
return () => clearInterval(intervalIdRef.current);
}, [isRunning]);
return (
<>
<IconButton onClick={handleStop}>
<StopIcon />
</IconButton>
<IconButton onClick={handleBack}>
<ArrowBackIcon />
</IconButton>
<IconButton onClick={handleNext}>
<ArrowForwardIcon />
</IconButton>
<Slider value={value} onChange={handleChange} />
</>
);
}