如何使用useRef获取Material-UI Slider组件的值
解决Material-UI Slider用useRef无法获取值的问题
问题描述
我想避免Slider组件在值变化时重新渲染,打算用useRef替代useState,但没法通过useRef获取Slider的值——打印ref.current得到的是嵌套span元素,没有value属性,无法用ref.current.value取值。
代码示例
import * as React from "react"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; import Stack from "@mui/material/Stack"; import Slider from "@mui/material/Slider"; import VolumeDown from "@mui/icons-material/VolumeDown"; import VolumeUp from "@mui/icons-material/VolumeUp"; export default function SliderInput() { console.log("Rendering slider input"); const sliderRef = React.useRef(); return ( <Box sx={{ width: 200 }}> <Stack spacing={2} direction="row" sx={{ mb: 1 }} alignItems="center"> <VolumeDown /> <Slider ref={sliderRef} aria-label="Volume" defaultValue={30} valueLabelDisplay="auto" /> <VolumeUp /> </Stack> <Button variant="contained" onClick={() => console.log(sliderRef.current)} > Console Log Color </Button> </Box> ); }
解决方案
1. 使用组件专属的inputRef属性
Material-UI的Slider是封装后的复合组件,直接用ref拿到的是外层容器元素。改用组件提供的inputRef属性,就能获取到底层的input元素,进而拿到value:
<Slider inputRef={sliderRef} // 替换原有的ref属性 aria-label="Volume" defaultValue={30} valueLabelDisplay="auto" />
之后点击按钮,就能通过sliderRef.current.value获取当前滑块值。
2. 用onChange配合useRef手动维护值
如果不想依赖底层input元素,可在滑块值变化时,把新值存入ref中,既不会触发组件重新渲染,又能实时拿到最新值:
export default function SliderInput() { console.log("Rendering slider input"); const sliderValueRef = React.useRef(30); // 初始化值与defaultValue保持一致 const handleSliderChange = (event, newValue) => { sliderValueRef.current = newValue; }; return ( <Box sx={{ width: 200 }}> <Stack spacing={2} direction="row" sx={{ mb: 1 }} alignItems="center"> <VolumeDown /> <Slider aria-label="Volume" defaultValue={30} valueLabelDisplay="auto" onChange={handleSliderChange} /> <VolumeUp /> </Stack> <Button variant="contained" onClick={() => console.log(sliderValueRef.current)} > Console Log Value </Button> </Box> ); }
注意事项
- 复合组件通常不会把内部核心元素暴露给普通
ref,要留意组件文档里提供的专属ref属性(如inputRef、rootRef)。 - 手动维护ref值时,初始化值要和Slider的
defaultValue或value保持一致,避免初始状态不一致的问题。
内容的提问来源于stack exchange,提问作者Simon1
相关产品推荐
相关产品推荐

