Javascript 自定义元件样式被材质UI样式覆盖
有关问题请浏览: 我正在材质UI上创建一个组件库。使用JSS,我希望能够将样式传递给我的自定义组件。然而,我对MaterialUI的根样式有一些问题,这些根样式比我要传递的更为特殊。我尝试过用classes语法覆盖materialui组件的默认样式,但它只是创建了另一个具有类似名称和更高特性的类makeStyles-root-51 使用自定义组件:Javascript 自定义元件样式被材质UI样式覆盖,javascript,reactjs,material-ui,react-component,jss,Javascript,Reactjs,Material Ui,React Component,Jss,有关问题请浏览: 我正在材质UI上创建一个组件库。使用JSS,我希望能够将样式传递给我的自定义组件。然而,我对MaterialUI的根样式有一些问题,这些根样式比我要传递的更为特殊。我尝试过用classes语法覆盖materialui组件的默认样式,但它只是创建了另一个具有类似名称和更高特性的类makeStyles-root-51 使用自定义组件: import React from 'react'; import {gSelect} from 'g-react-component-librar
import React from 'react';
import {gSelect} from 'g-react-component-library/dist'
import {createUseStyles} from 'react-jss'
const useStyles = createUseStyles({
gSelect: {margin: "15px"},
example: {float: "left", display: "inline-block", whiteSpace: 'nowrap', verticalAlign: 'top'}
});
function App() {
const classes = useStyles();
return (
<div className={classes.example}>
<div className={classes.separator}>
<div>Selects:</div>
<gSelect default={1} classes={{gSelect: classes.gSelect}} callback={(e)=>{console.log(`${e} selected`)}} options={[1,2,3,4]}/>
<gSelect default={'One'} classes={{gSelect: classes.gSelect}} callback={(e)=>{console.log(`${e} selected`)}} options={["One", "Two", "Three", "Four"]}/>
</div>
</div>
);
}
export default App;
import React, {useState} from 'react';
import {Button, Select, FormControl, MenuItem, InputLabel} from '@material-ui/core'
import {makeStyles} from '@material-ui/styles'
import PropTypes from 'prop-types'
const gSelect = (props) => {
const [value, setValue] = useState();
const handleChange = event => {
props.callback(event.target.value);
setValue(event.target.value);
};
const useStyles = makeStyles({
select: {
border: 'solid #33333366 1px',
color: 'rgba(51, 51, 51, 0.66)',
fontWeight: '700',
backgroundColor: 'white',
outline: 'none',
borderRadius: '5px',
textAlign: 'left',
width: '300px',
position: 'relative',
},
root: {
}
});
const classes = useStyles(props);
return (
<FormControl classes={{root: classes.gSelect}}>
<InputLabel id="demo-simple-select-label">{props.default}</InputLabel>
<Select value={value} onChange={handleChange} className={classes.select}>
{props.options.map((option, index) => {
return <MenuItem key={`${option}_${index}`} value={option}>{option}</MenuItem>
})}
</Select>
</FormControl>
)
};
gSelect.propTypes = {
callback: PropTypes.func.isRequired,
options: PropTypes.array.isRequired,
default: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]).isRequired,
disabled: PropTypes.bool,
width: PropTypes.string
};
module.exports = {
gSelect
};
import React, {useState} from 'react';
import {Button, Select, FormControl, MenuItem, InputLabel} from '@material-ui/core'
import {makeStyles} from '@material-ui/styles'
import PropTypes from 'prop-types'
const gSelect = (props) => {
const [value, setValue] = useState();
const handleChange = event => {
props.callback(event.target.value);
setValue(event.target.value);
};
const useStyles = makeStyles({
select: {
border: 'solid #33333366 1px',
color: 'rgba(51, 51, 51, 0.66)',
fontWeight: '700',
backgroundColor: 'white',
outline: 'none',
borderRadius: '5px',
textAlign: 'left',
width: '300px',
position: 'relative',
}
});
const classes = useStyles();
return (
<FormControl className={props.className}>
<InputLabel id="demo-simple-select-label">{props.default}</InputLabel>
<Select value={value} onChange={handleChange} className={classes.select}>
{props.options.map((option, index) => {
return <MenuItem key={`${option}_${index}`} value={option}>{option}</MenuItem>
})}
</Select>
</FormControl>
)
};
gSelect.propTypes = {
callback: PropTypes.func.isRequired,
options: PropTypes.array.isRequired,
default: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]).isRequired,
disabled: PropTypes.bool,
width: PropTypes.string
};
module.exports = {
gSelect
};
实际自定义组件:
import React from 'react';
import {gSelect} from 'g-react-component-library/dist'
import {createUseStyles} from 'react-jss'
const useStyles = createUseStyles({
gSelect: {margin: "15px"},
example: {float: "left", display: "inline-block", whiteSpace: 'nowrap', verticalAlign: 'top'}
});
function App() {
const classes = useStyles();
return (
<div className={classes.example}>
<div className={classes.separator}>
<div>Selects:</div>
<gSelect default={1} classes={{gSelect: classes.gSelect}} callback={(e)=>{console.log(`${e} selected`)}} options={[1,2,3,4]}/>
<gSelect default={'One'} classes={{gSelect: classes.gSelect}} callback={(e)=>{console.log(`${e} selected`)}} options={["One", "Two", "Three", "Four"]}/>
</div>
</div>
);
}
export default App;
import React, {useState} from 'react';
import {Button, Select, FormControl, MenuItem, InputLabel} from '@material-ui/core'
import {makeStyles} from '@material-ui/styles'
import PropTypes from 'prop-types'
const gSelect = (props) => {
const [value, setValue] = useState();
const handleChange = event => {
props.callback(event.target.value);
setValue(event.target.value);
};
const useStyles = makeStyles({
select: {
border: 'solid #33333366 1px',
color: 'rgba(51, 51, 51, 0.66)',
fontWeight: '700',
backgroundColor: 'white',
outline: 'none',
borderRadius: '5px',
textAlign: 'left',
width: '300px',
position: 'relative',
},
root: {
}
});
const classes = useStyles(props);
return (
<FormControl classes={{root: classes.gSelect}}>
<InputLabel id="demo-simple-select-label">{props.default}</InputLabel>
<Select value={value} onChange={handleChange} className={classes.select}>
{props.options.map((option, index) => {
return <MenuItem key={`${option}_${index}`} value={option}>{option}</MenuItem>
})}
</Select>
</FormControl>
)
};
gSelect.propTypes = {
callback: PropTypes.func.isRequired,
options: PropTypes.array.isRequired,
default: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]).isRequired,
disabled: PropTypes.bool,
width: PropTypes.string
};
module.exports = {
gSelect
};
import React, {useState} from 'react';
import {Button, Select, FormControl, MenuItem, InputLabel} from '@material-ui/core'
import {makeStyles} from '@material-ui/styles'
import PropTypes from 'prop-types'
const gSelect = (props) => {
const [value, setValue] = useState();
const handleChange = event => {
props.callback(event.target.value);
setValue(event.target.value);
};
const useStyles = makeStyles({
select: {
border: 'solid #33333366 1px',
color: 'rgba(51, 51, 51, 0.66)',
fontWeight: '700',
backgroundColor: 'white',
outline: 'none',
borderRadius: '5px',
textAlign: 'left',
width: '300px',
position: 'relative',
}
});
const classes = useStyles();
return (
<FormControl className={props.className}>
<InputLabel id="demo-simple-select-label">{props.default}</InputLabel>
<Select value={value} onChange={handleChange} className={classes.select}>
{props.options.map((option, index) => {
return <MenuItem key={`${option}_${index}`} value={option}>{option}</MenuItem>
})}
</Select>
</FormControl>
)
};
gSelect.propTypes = {
callback: PropTypes.func.isRequired,
options: PropTypes.array.isRequired,
default: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]).isRequired,
disabled: PropTypes.bool,
width: PropTypes.string
};
module.exports = {
gSelect
};
你做错了。GSelect应该接收如下类:
应用程序内:
<GSelect default={1} classes={{gSelect:classes.gSelect}} callback={(e)=>{console.log(`${e} selected`)}} options={[1,2,3,4]}/>
编辑:至于我最初关于在组件外部创建钩子的评论,我的意思是:
// move this outside of your render
const useStyles = createUseStyles({
gSelect: {margin: "15px"},
separator: {marginTop: "15px"},
example: {float: "left", display: "inline-block", whiteSpace: 'nowrap', verticalAlign: 'top'}
});
function App() {
// use it inside of your render
const classes = useStyles();
...
}
通读本节和以下两部分,过一会儿,它会单击:最终将样式传递给自定义组件的解决方案非常简单。虽然@Adam用它的措辞回答了我的问题,但我最终得到的解决方案如下: 使用自定义组件:
import React from 'react';
import {gSelect} from 'g-react-component-library/dist'
import { makeStyles } from "@material-ui/core/styles";
const useStyles = makeStyles ({
gSelect: {margin: "15px"},
example: {float: "left", display: "inline-block", whiteSpace: 'nowrap', verticalAlign: 'top'}
});
function App() {
const classes = useStyles();
return (
<div className={classes.example}>
<div className={classes.separator}>
<div>Selects:</div>
<gSelect default={1} className={classes.gSelect} callback={(e)=>{console.log(`${e} selected`)}} options={[1,2,3,4]}/>
<gSelect default={'One'} className={classes.gSelect} callback={(e)=>{console.log(`${e} selected`)}} options={["One", "Two", "Three", "Four"]}/>
</div>
</div>
);
}
export default App;
上述修正包括:
已在上使用className={props.className}
你不应该在组件内部创建useStyles钩子,这会破坏它的用途。怎么会呢?如果我想在material UI上创建一个自定义组件库,你必须以某种方式为它提供自定义样式。我在下面的回答中解释过——问题的关键是类应该通过道具来实现,你应该将这些道具传递给你的钩子——material UI具有将传入类连接到你自己的类的所有魔力。我个人更喜欢withStyles hoc,因为所有这些逻辑都是为您自动处理的,您不必担心忘记将道具传递给useStyles挂钩。@Adam,我已经做了您建议的更改。然而,我仍然遇到这样一个问题:MUI的根类具有更高的特异性,并且覆盖了我的边界。另外,我已经从源代码中为这个问题删减了很多代码,因此,如果有一些突出的问题,可能就是您所看到的。在我最初的问题中,我意识到我传递到组件中的样式与它在内部用于自定义选择的样式相同。这只是我为问题编辑内容的一个错误。我应该在更新的问题中修正它。如果你可以发布一个codepen/stackblitz来证明一个问题不一定是这个确切的代码,只是一些类似的东西,它会走很长的路。