反应:带有自定义钩子的滑块无法正常工作

Posted

技术标签:

【中文标题】反应:带有自定义钩子的滑块无法正常工作【英文标题】:React: Slider with custom hook not working properly 【发布时间】:2019-12-17 09:38:12 【问题描述】:

我正在尝试使用滑块 ui 元素创建自定义挂钩。我的目标是能够从父元素访问滑块值,以便更新其他一些 ui 部分。

但是,滑块值似乎没有正确更新:当用户尝试拖动滑块工具提示时,它只移动了一步。似乎在调用 useEffect 后鼠标事件不再被跟踪。

我可以做些什么来解决这个问题并获得平滑的拖动行为?

这是我的代码 (sandbox):

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Demo from './demo';

ReactDOM.render(<Demo />, document.querySelector('#root')); 

demo.js

import React,  useEffect  from "react";
import useSlider from "./slider";

function CustomizedSlider() 
  const [CustomSlider, sliderValue] = useSlider("Slider", 50);

  useEffect(() => 
    console.log("Slider value: " + sliderValue);
  , [sliderValue]);

  return <CustomSlider />;


export default CustomizedSlider;

slider.js

import React,  useState  from "react";
import  withStyles, makeStyles  from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Slider from "@material-ui/core/Slider";
import Typography from "@material-ui/core/Typography";

const useStyles = makeStyles(theme => (...
));

const PrettoSlider = withStyles(...
)(Slider);

export default function useSlider(label, defaultState) 
  const classes = useStyles();
  const [state, setState] = useState(defaultState);

  const CustomSlider = () => 
    return (
      <Paper className=classes.root>
        <div className=classes.margin />
        <Typography gutterBottom>label</Typography>
        <PrettoSlider
          valueLabelDisplay="auto"
          aria-label="pretto slider"
          defaultValue=50
          value=state
          onChange=(event, v) => 
            setState(v);
          
        />
      </Paper>
    );
  ;

  return [CustomSlider, state];

非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

问题是您的CustomSlider 是每次渲染的新组件类型,因为它每次都是唯一的功能。这会导致它在每次渲染时卸载/重新安装,而不仅仅是重新渲染,这会导致各种问题(如您所见)。

我认为您真的只想要一个自定义组件,而不是自定义钩子。以下是一种只需对初始代码进行少量更改即可构建它的方法。

demo.js

import React,  useEffect  from "react";
import CustomSlider from "./CustomSlider";

function CustomizedSlider() 
  const [value, setValue] = React.useState(50);

  useEffect(() => 
    console.log("Slider value: " + value);
  , [value]);

  return <CustomSlider label="Slider" value=value setValue=setValue />;


export default CustomizedSlider;

CustomSlider.js

import React from "react";
import  withStyles, makeStyles  from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Slider from "@material-ui/core/Slider";
import Typography from "@material-ui/core/Typography";

const useStyles = makeStyles(theme => (
  root: 
    width: 300 + 24 * 2,
    padding: 24
  ,
  margin: 
    height: theme.spacing(1)
  
));

const PrettoSlider = withStyles(
  root: 
    color: "#a2df77",
    height: 8
  ,
  thumb: 
    height: 24,
    width: 24,
    backgroundColor: "#fff",
    border: "2px solid currentColor",
    marginTop: -8,
    marginLeft: -12,
    "&:focus,&:hover,&$active": 
      boxShadow: "inherit"
    
  ,
  active: ,
  valueLabel: 
    left: "calc(-50% + 4px)"
  ,
  track: 
    height: 8,
    borderRadius: 4
  ,
  rail: 
    height: 8,
    borderRadius: 4
  
)(Slider);

const CustomSlider = ( label, value, setValue ) => 
  const classes = useStyles();
  return (
    <Paper className=classes.root>
      <div className=classes.margin />
      <Typography gutterBottom>label</Typography>
      <PrettoSlider
        valueLabelDisplay="auto"
        aria-label="pretto slider"
        defaultValue=50
        value=value
        onChange=(event, v) => 
          setValue(v);
        
      />
    </Paper>
  );
;
export default CustomSlider;

【讨论】:

以上是关于反应:带有自定义钩子的滑块无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

更改 MPVolumeView 的滑块

光滑的滑块同步 - 断点上的自定义箭头

自定义 jquery 移动滑块标签

用于获取数据的自定义 React 钩子无法正常工作

在自定义反应钩子中使用 axios

如何在光滑的滑块中创建自定义箭头以在悬停时更改图像?