Material UI this.state 彩色背景错误
Material UI this.state error for color background
我的眼睛受伤了,我试图让滑块不仅可以改变按钮的半径,还可以改变颜色。
这 sandbox 成功更新了半径。
Here is the code:
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid";
import Slider from "@material-ui/core/Slider";
import Input from "@material-ui/core/Input";
import Button from "@material-ui/core/Button";
import reactCSS from "reactcss";
import { SketchPicker } from "react-color";
const useStyles = makeStyles((theme) => ({
root: {
"& > *": {
margin: theme.spacing(1)
}
},
Button: {
width: 150,
height: 50,
borderRadius: "var(--borderRadius)"
}
}));
export default function InputSlider() {
const classes = useStyles();
const [value, setValue] = React.useState(30);
const handleSliderChange = (event, newValue) => {
setValue(newValue);
};
const handleInputChange = (event) => {
setValue(event.target.value === "" ? "" : Number(event.target.value));
};
const handleBlur = () => {
if (value < 0) {
setValue(0);
} else if (value > 30) {
setValue(30);
}
};
return (
<div className={classes.root}>
<style>
{`:root {
--borderRadius = ${value}px;
}`}
</style>
<Button
style={{ borderRadius: value }}
variant="contained"
color="primary"
value="value"
onChange={handleSliderChange}
className={classes.Button}
>
Fire laser
</Button>
<Grid container spacing={2}>
<Grid item xs>
<Slider
value={typeof value === "number" ? value : 0}
onChange={handleSliderChange}
aria-labelledby="input-slider"
/>
</Grid>
<Grid item>
<Input
value={value}
margin="dense"
onChange={handleInputChange}
onBlur={handleBlur}
inputProps={{
step: 10,
min: 0,
max: 24,
type: "number"
}}
/>
</Grid>
</Grid>
</div>
);
}
现在我正在研究如何使用 color picker 更改按钮的背景颜色,最终还会更改字体颜色。
我收到 this.state
的错误消息。有什么建议?
这是一个正在进行中的不同沙箱,并且有错误消息 - https://codesandbox.io/s/material-demo-forked-l35qy?file=/demo.js
这是带有错误消息的代码:
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid";
import Slider from "@material-ui/core/Slider";
import Input from "@material-ui/core/Input";
import Button from "@material-ui/core/Button";
import reactCSS from "reactcss";
import { SketchPicker } from "react-color";
const useStyles = makeStyles((theme) => ({
root: {
"& > *": {
margin: theme.spacing(1)
}
},
Button: {
width: 150,
height: 50,
borderRadius: "var(--borderRadius)",
background: `rgba(${this.state.color.r}, ${this.state.color.g}, ${this.state.color.b}, ${this.state.color.a})`
},
color: {
width: "36px",
height: "14px",
borderRadius: "2px",
background: `rgba(${this.state.color.r}, ${this.state.color.g}, ${this.state.color.b}, ${this.state.color.a})`
},
swatch: {
padding: "5px",
background: "#fff",
borderRadius: "1px",
display: "inline-block",
cursor: "pointer"
},
popover: {
position: "absolute",
zIndex: "2"
},
cover: {
position: "fixed",
top: "0px",
right: "0px",
bottom: "0px",
left: "0px"
}
}));
export default function InputSlider() {
const classes = useStyles();
const [value, setValue] = React.useState(30);
const handleSliderChange = (event, newValue) => {
setValue(newValue);
};
const handleInputChange = (event) => {
setValue(event.target.value === "" ? "" : Number(event.target.value));
};
const handleBlur = () => {
if (value < 0) {
setValue(0);
} else if (value > 30) {
setValue(30);
}
};
const handleClick = () => {
this.setState({ displayColorPicker: !this.state.displayColorPicker });
};
const handleClose = () => {
this.setState({ displayColorPicker: false });
};
const handleChange = (color) => {
this.setState({ color: color.rgb });
};
return (
<div className={classes.root}>
<style>
{`:root {
--borderRadius = ${value}px;
}`}
</style>
<Button
style={{ borderRadius: value }}
variant="contained"
color="primary"
value="value"
onChange={handleSliderChange}
className={classes.Button}
>
Fire laser
</Button>
<Grid container spacing={2}>
<Grid item xs>
<Slider
value={typeof value === "number" ? value : 0}
onChange={handleSliderChange}
aria-labelledby="input-slider"
/>
</Grid>
<Grid item>
<Input
value={value}
margin="dense"
onChange={handleInputChange}
onBlur={handleBlur}
inputProps={{
step: 10,
min: 0,
max: 24,
type: "number"
}}
/>
</Grid>
</Grid>
<div>
<Button style={useStyles.color}></Button>
<div style={useStyles.swatch} onClick={this.handleClick}>
<div style={useStyles.color} />
</div>
{this.state.displayColorPicker ? (
<div style={useStyles.popover}>
<div style={useStyles.cover} onClick={this.handleClose} />
<SketchPicker
color={this.state.color}
onChange={this.handleChange}
/>
</div>
) : null}
</div>
</div>
);
}
您不能在 useStyles 中使用状态,因为您只能访问主题,而不能访问任何道具。您应该改用 makeStyles 调用,因为它至少可以让您传入一些道具。这已经在这里得到回答,并且有一个很好的例子。
另一个问题是您使用的是基于功能的组件,其中状态的编写方式不同。我已经使用 useState 钩子为您重写了它,所以希望这至少能得到要使用的颜色。
export default function InputSlider() {
const classes = useStyles();
const [value, setValue] = React.useState(30);
const [color, setColor] = React.useState({ background: "#fff" });
const handleSliderChange = (event, newValue) => {
setValue(newValue);
};
const handleInputChange = (event) => {
setValue(event.target.value === "" ? "" : Number(event.target.value));
};
const handleBlur = () => {
if (value < 0) {
setValue(0);
} else if (value > 30) {
setValue(30);
}
};
const handleClick = (color) => {
setColor(color);
};
const handleClose = () => {
setColor({ displayColorPicker: false });
};
const handleChange = (color) => {
setColor(color);
};
return (
<div className={classes.root}>
<style>
{`:root {
--borderRadius = ${value}px;
}`}
</style>
<Button
style={{ borderRadius: value }}
variant="contained"
color="primary"
value="value"
onChange={handleSliderChange}
className={classes.Button}
>
Fire laser
</Button>
<Grid container spacing={2}>
<Grid item xs>
<Slider
value={typeof value === "number" ? value : 0}
onChange={handleSliderChange}
aria-labelledby="input-slider"
/>
</Grid>
<Grid item>
<Input
value={value}
margin="dense"
onChange={handleInputChange}
onBlur={handleBlur}
inputProps={{
step: 10,
min: 0,
max: 24,
type: "number"
}}
/>
</Grid>
</Grid>
<div>
<Button style={useStyles.color}></Button>
<div style={useStyles.swatch} onClick={handleClick}>
<div style={useStyles.color} />
</div>
{color ? (
<div style={useStyles.popover}>
<div style={useStyles.cover} onClick={handleClose} />
<SketchPicker color={color} onChange={handleChange} />
</div>
) : null}
</div>
</div>
);
}
@RichardHpa 是正确的,您无法访问 makeStyles 中的状态,并且您混淆了 class 组件和功能组件。在你的情况下,你应该一直使用 useState()
。
您已经有了如何设置边框半径的示例,因此您可以复制该流程以在背景颜色中使用它,直接在 Button 上设置样式。
这是代码框:
https://codesandbox.io/s/material-demo-forked-djh78?file=/demo.js
<Button
style={{
borderRadius: value,
background: `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`
// may need another color picker for text coloe. otherwise, bg color will be the same as text color.
// color: `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`
}}
variant="contained"
color="primary"
value="value"
onChange={handleSliderChange}
className={classes.Button}
>
无需为我评分,@RichardHpa 值得称赞。
我的眼睛受伤了,我试图让滑块不仅可以改变按钮的半径,还可以改变颜色。
这 sandbox 成功更新了半径。
Here is the code:
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid";
import Slider from "@material-ui/core/Slider";
import Input from "@material-ui/core/Input";
import Button from "@material-ui/core/Button";
import reactCSS from "reactcss";
import { SketchPicker } from "react-color";
const useStyles = makeStyles((theme) => ({
root: {
"& > *": {
margin: theme.spacing(1)
}
},
Button: {
width: 150,
height: 50,
borderRadius: "var(--borderRadius)"
}
}));
export default function InputSlider() {
const classes = useStyles();
const [value, setValue] = React.useState(30);
const handleSliderChange = (event, newValue) => {
setValue(newValue);
};
const handleInputChange = (event) => {
setValue(event.target.value === "" ? "" : Number(event.target.value));
};
const handleBlur = () => {
if (value < 0) {
setValue(0);
} else if (value > 30) {
setValue(30);
}
};
return (
<div className={classes.root}>
<style>
{`:root {
--borderRadius = ${value}px;
}`}
</style>
<Button
style={{ borderRadius: value }}
variant="contained"
color="primary"
value="value"
onChange={handleSliderChange}
className={classes.Button}
>
Fire laser
</Button>
<Grid container spacing={2}>
<Grid item xs>
<Slider
value={typeof value === "number" ? value : 0}
onChange={handleSliderChange}
aria-labelledby="input-slider"
/>
</Grid>
<Grid item>
<Input
value={value}
margin="dense"
onChange={handleInputChange}
onBlur={handleBlur}
inputProps={{
step: 10,
min: 0,
max: 24,
type: "number"
}}
/>
</Grid>
</Grid>
</div>
);
}
现在我正在研究如何使用 color picker 更改按钮的背景颜色,最终还会更改字体颜色。
我收到 this.state
的错误消息。有什么建议?
这是一个正在进行中的不同沙箱,并且有错误消息 - https://codesandbox.io/s/material-demo-forked-l35qy?file=/demo.js
这是带有错误消息的代码:
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid";
import Slider from "@material-ui/core/Slider";
import Input from "@material-ui/core/Input";
import Button from "@material-ui/core/Button";
import reactCSS from "reactcss";
import { SketchPicker } from "react-color";
const useStyles = makeStyles((theme) => ({
root: {
"& > *": {
margin: theme.spacing(1)
}
},
Button: {
width: 150,
height: 50,
borderRadius: "var(--borderRadius)",
background: `rgba(${this.state.color.r}, ${this.state.color.g}, ${this.state.color.b}, ${this.state.color.a})`
},
color: {
width: "36px",
height: "14px",
borderRadius: "2px",
background: `rgba(${this.state.color.r}, ${this.state.color.g}, ${this.state.color.b}, ${this.state.color.a})`
},
swatch: {
padding: "5px",
background: "#fff",
borderRadius: "1px",
display: "inline-block",
cursor: "pointer"
},
popover: {
position: "absolute",
zIndex: "2"
},
cover: {
position: "fixed",
top: "0px",
right: "0px",
bottom: "0px",
left: "0px"
}
}));
export default function InputSlider() {
const classes = useStyles();
const [value, setValue] = React.useState(30);
const handleSliderChange = (event, newValue) => {
setValue(newValue);
};
const handleInputChange = (event) => {
setValue(event.target.value === "" ? "" : Number(event.target.value));
};
const handleBlur = () => {
if (value < 0) {
setValue(0);
} else if (value > 30) {
setValue(30);
}
};
const handleClick = () => {
this.setState({ displayColorPicker: !this.state.displayColorPicker });
};
const handleClose = () => {
this.setState({ displayColorPicker: false });
};
const handleChange = (color) => {
this.setState({ color: color.rgb });
};
return (
<div className={classes.root}>
<style>
{`:root {
--borderRadius = ${value}px;
}`}
</style>
<Button
style={{ borderRadius: value }}
variant="contained"
color="primary"
value="value"
onChange={handleSliderChange}
className={classes.Button}
>
Fire laser
</Button>
<Grid container spacing={2}>
<Grid item xs>
<Slider
value={typeof value === "number" ? value : 0}
onChange={handleSliderChange}
aria-labelledby="input-slider"
/>
</Grid>
<Grid item>
<Input
value={value}
margin="dense"
onChange={handleInputChange}
onBlur={handleBlur}
inputProps={{
step: 10,
min: 0,
max: 24,
type: "number"
}}
/>
</Grid>
</Grid>
<div>
<Button style={useStyles.color}></Button>
<div style={useStyles.swatch} onClick={this.handleClick}>
<div style={useStyles.color} />
</div>
{this.state.displayColorPicker ? (
<div style={useStyles.popover}>
<div style={useStyles.cover} onClick={this.handleClose} />
<SketchPicker
color={this.state.color}
onChange={this.handleChange}
/>
</div>
) : null}
</div>
</div>
);
}
您不能在 useStyles 中使用状态,因为您只能访问主题,而不能访问任何道具。您应该改用 makeStyles 调用,因为它至少可以让您传入一些道具。这已经在这里得到回答,并且有一个很好的例子。
另一个问题是您使用的是基于功能的组件,其中状态的编写方式不同。我已经使用 useState 钩子为您重写了它,所以希望这至少能得到要使用的颜色。
export default function InputSlider() {
const classes = useStyles();
const [value, setValue] = React.useState(30);
const [color, setColor] = React.useState({ background: "#fff" });
const handleSliderChange = (event, newValue) => {
setValue(newValue);
};
const handleInputChange = (event) => {
setValue(event.target.value === "" ? "" : Number(event.target.value));
};
const handleBlur = () => {
if (value < 0) {
setValue(0);
} else if (value > 30) {
setValue(30);
}
};
const handleClick = (color) => {
setColor(color);
};
const handleClose = () => {
setColor({ displayColorPicker: false });
};
const handleChange = (color) => {
setColor(color);
};
return (
<div className={classes.root}>
<style>
{`:root {
--borderRadius = ${value}px;
}`}
</style>
<Button
style={{ borderRadius: value }}
variant="contained"
color="primary"
value="value"
onChange={handleSliderChange}
className={classes.Button}
>
Fire laser
</Button>
<Grid container spacing={2}>
<Grid item xs>
<Slider
value={typeof value === "number" ? value : 0}
onChange={handleSliderChange}
aria-labelledby="input-slider"
/>
</Grid>
<Grid item>
<Input
value={value}
margin="dense"
onChange={handleInputChange}
onBlur={handleBlur}
inputProps={{
step: 10,
min: 0,
max: 24,
type: "number"
}}
/>
</Grid>
</Grid>
<div>
<Button style={useStyles.color}></Button>
<div style={useStyles.swatch} onClick={handleClick}>
<div style={useStyles.color} />
</div>
{color ? (
<div style={useStyles.popover}>
<div style={useStyles.cover} onClick={handleClose} />
<SketchPicker color={color} onChange={handleChange} />
</div>
) : null}
</div>
</div>
);
}
@RichardHpa 是正确的,您无法访问 makeStyles 中的状态,并且您混淆了 class 组件和功能组件。在你的情况下,你应该一直使用 useState()
。
您已经有了如何设置边框半径的示例,因此您可以复制该流程以在背景颜色中使用它,直接在 Button 上设置样式。
这是代码框:
https://codesandbox.io/s/material-demo-forked-djh78?file=/demo.js
<Button
style={{
borderRadius: value,
background: `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`
// may need another color picker for text coloe. otherwise, bg color will be the same as text color.
// color: `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`
}}
variant="contained"
color="primary"
value="value"
onChange={handleSliderChange}
className={classes.Button}
>
无需为我评分,@RichardHpa 值得称赞。