reactjs - 反应:带有自定义钩子的滑块无法正常工作
问题描述
我正在尝试使用滑块 ui 元素创建自定义挂钩。我的目标是能够从父元素访问滑块值,以便更新其他一些 ui 部分。
但是,滑块值似乎没有正确更新:当用户尝试拖动滑块工具提示时,它只移动了一步。在调用 useEffect 后,似乎停止跟踪鼠标事件。
我能做些什么来解决这个问题并获得平滑的拖动行为?
这是我的代码(沙箱):
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Demo from './demo';
ReactDOM.render(<Demo />, document.querySelector('#root'));
演示.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;
滑块.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];
}
非常感谢你的帮助!
解决方案
问题是你CustomSlider
的每次渲染都是一个新的组件类型,因为它每次都是一个独特的功能。这会导致它在每次渲染时卸载/重新安装,而不仅仅是重新渲染,这会导致各种问题(如您所见)。
我认为您真的只想要一个自定义组件,而不是自定义钩子。以下是一种只需对初始代码进行少量更改即可构建它的方法。
演示.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;
推荐阅读
- excel - 如何将格式设置为 .csv 文件中的数字列?
- stl - 如何在我的凉亭模型上添加一个 png 文件作为徽标,该模型是一个 .stl 文件并以 .sdf.jinja 格式编写?
- r - R:按字母差异过滤单词向量
- python - Otree Page not found 服务器错误 404。如何在域名中添加子 url?
- java - 如何在 application-definition.json 文件中配置 RabbitMQ 连接并使用交换设置队列?
- kotlin - Kotlin/JVM 上的 Grpc
- java - 为类成员扩展 Spring Bean 验证
- amazon-cloudwatch - 使用 CDK 部署 AWS Cloudwatch 控制面板:如何隐藏指标
- typescript - 如何根据 TypeScript 中 const 对象的键/值创建对象类型?
- python-3.x - 如何比较 Django 模板中的两个 for 循环索引号?