我试图使用Material Ui滑块和useState创建字体大小和字体粗细预览器,但当我在单击第二个滑块后单击第一个滑块时,第一个滑块会重复。
这是我的代码:
import React from "react";
import { withStyles, makeStyles } from "@material-ui/core/styles";
import Slider from "@material-ui/core/Slider";
import Typography from "@material-ui/core/Typography";
import Container from "@material-ui/core/Container";
import TextField from '@mui/material/TextField';
const useStyles = makeStyles((theme) => ({
root: {
width: 300 + theme.spacing(3) * 2
},
margin: {
height: theme.spacing(3)
}
}));
const iOSBoxShadow =
"0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.13),0 0 0 1px rgba(0,0,0,0.02)";
const marks = [
{
value: 0
},
{
value: 25
},
{
value: 50
},
{
value: 75
},
{
value: 100
}
];
const IOSSlider = withStyles({
root: {
color: "#3880ff",
height: 2,
padding: "15px 0"
},
thumb: {
height: 28,
width: 28,
backgroundColor: "#fff",
boxShadow: iOSBoxShadow,
marginTop: -14,
marginLeft: -14,
"&:focus, &:hover, &$active": {
boxShadow:
"0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)",
// Reset on touch devices, it doesn't add specificity
"@media (hover: none)": {
boxShadow: iOSBoxShadow
}
}
},
active: {},
valueLabel: {
left: "calc(-50% + 12px)",
top: -22,
"& *": {
background: "transparent",
color: "#000"
}
},
track: {
height: 2
},
rail: {
height: 2,
opacity: 0.5,
backgroundColor: "#bfbfbf"
},
mark: {
backgroundColor: "#bfbfbf",
height: 8,
width: 1,
marginTop: -3
},
markActive: {
opacity: 1,
backgroundColor: "currentColor"
}
})(Slider);
export default function CustomizedSlider() {
const classes = useStyles();
const [userFontSize, setUserFontSize] = React.useState("1rem");
const [userFontWeight, setUserFontWeight] = React.useState("300");
const [sliderSizeTracker, setSliderSizeTracker] = React.useState(0);
const [sliderWeightTracker, setSliderWeightTracker] = React.useState(999);
const handleSizeChange = (e, newSizeValue) => {
switch (newSizeValue) {
case 0: {
setUserFontSize("1rem");
setSliderSizeTracker(0);
break;
}
case 25: {
setUserFontSize("1.19rem");
setSliderSizeTracker(25);
break;
}
case 50: {
setUserFontSize("1.37rem");
setSliderSizeTracker(50);
break;
}
case 75: {
setUserFontSize("1.55rem");
setSliderSizeTracker(75);
break;
}
case 100: {
setUserFontSize("1.75rem");
setSliderSizeTracker(100);
break;
}
default: {
break;
}
}
};
const handleWeightChange = (e, newWeightValue) => {
switch (newWeightValue) {
case 0: {
setUserFontWeight("300");
setSliderWeightTracker(0);
break;
}
case 25: {
setUserFontWeight("400");
setSliderWeightTracker(25);
break;
}
case 50: {
setUserFontWeight("500");
setSliderWeightTracker(50);
break;
}
case 75: {
setUserFontWeight("700");
setSliderWeightTracker(75);
break;
}
case 100: {
setUserFontWeight("900");
setSliderWeightTracker(100);
break;
}
default: {
break;
}
}
};
return (
<Container maxWidth="sm" style={{ marginTop: "2em" }}>
<div className={classes.root}>
<Typography gutterBottom>Font Size Slider</Typography>
<IOSSlider
aria-label="Font Size Slider"
key={sliderSizeTracker}
defaultValue={sliderSizeTracker}
marks={marks}
step={25}
onChangeCommitted={handleSizeChange}
valueLabelDisplay="off"
/>
<Typography gutterBottom>Font Weight Slider</Typography>
<IOSSlider
aria-label="Font Weight Slider"
key={sliderWeightTracker}
defaultValue={sliderWeightTracker}
marks={marks}
step={25}
onChangeCommitted={handleWeightChange}
valueLabelDisplay="off"
/>
<div className={classes.margin} />
<TextField
sx={{ border: 'none', "& fieldset": { border: 'none' }, }}
margin="normal"
required
fullWidth
inputProps={{ style: { fontSize: `${userFontSize}`, fontWeight: `${userFontWeight}` } }}
defaultValue="The quick brown fox jumps over the lazy dog"
multiline
rows={2}
/>
</div>
</Container>
);
}
codesandbox
我认为这与我使用useState的方式有关,但功能本身似乎是有效的。