javascript - 使用类组件时如何根据屏幕大小断点更改 Material UIs Button 组件的 prop
问题描述
我正在使用 Material UI 的 Button 组件,并希望有条件地确定按钮的变体。也就是说,在中等及以上屏幕上,变体应为“轮廓”,当屏幕小于中等时,变体类型应为无。我正在使用一个类组件。我做了我的研究,看看其他人做了什么。我已经看到了使用 useMediaQuery 方法的方法,但这需要我将组件更改为功能组件。我不确定我是否知道这是否是一个好主意,因为该组件相当大,这意味着转换会有点混乱。我还尝试使用这样的三元运算符:
const variantType = theme.breakpoints.down("md") ? '' : 'outline';
<Button variant={variantType}>
Food Pick
</Button>
但这并没有起到作用。有没有其他方法可以做到这一点?
Update: Here is my code after trying to wrap the component but in a functional component but its giving an error:
import { withStyles, withTheme, useTheme } from '@material-ui/core';
import PropTypes from 'prop-types';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import Grid from '@material-ui/core/Grid';
import { PulseLoader } from 'react-spinners';
import Icon from '@material-ui/core/Icon';
import Chip from '@material-ui/core/Chip';
import useMediaQuery from '@material-ui/core/useMediaQuery';
const styles = theme => ({
beta: {
height: '17px',
fontSize: '12px',
marginLeft: '10px'
},
scrollContainer: {
flex: 1,
maxHeight: '400px',
minHeight: '300px',
overflowY: 'auto'
},
progressContainer: {
height: '350px',
},
modalDescription: {
color: theme.palette.text.secondary,
marginTop: '20px',
},
button: {
marginTop: '20px',
marginLeft: '10px',
marginRight: '10px',
},
smartSuggestContainer: {
textAlign: 'right',
paddingRight: '35px',
[theme.breakpoints.down('xs')]: {
display: 'flex',
justifyContent: 'center',
flexDirection: 'row',
margin: '40px 0'
},
},
});
export default function MyComponentWrapper({ ...rest }) {
const theme = useTheme();
const mediumScreen = useMediaQuery(theme.breakpoints.down('md'));
return <FoodDescriptions {...rest} mediumScreen={mediumScreen} />;
}
class FoodDescriptions extends Component {
static PAGE_SIZE = 25;
constructor(props) {
super(props);
this.state = {
showFoodDescriptionsModal: false,
dataLoaded: false,
data: [],
page: 0,
sortBy: 'return',
sortDir: 'desc',
};
}
componentDidMount() {
document.addEventListener('keydown', this.handleKeypress);
}
componentWillUnmount() {
document.removeEventListener('keydown', this.handleKeypress);
}
fetchData = async (page, sortBy, sortDir) => {
const { currentBotId } = this.props;
const offset = page * FoodDescriptions.PAGE_SIZE;
const data = await getFoodDescriptions(currentBotId, sortBy, sortDir, FoodDescriptions.PAGE_SIZE, offset);
this.setState({
dataLoaded: true,
data,
});
};
handleKeypress = (e) => {
const { showSnartConfigsModal } = this.state;
const { key } = e;
if (key === 'Escape' && showSnartConfigsModal) {
this.closeModal();
}
};
applyConfig = (botId, params) => {
const { updateConfig, botConfig, actions } = this.props;
updateConfig({ name: botConfig.name, config: Object.assign(botConfig.config, params) });
this.closeModal();
actions.showNotification({ data: 'Configuration has been applied' });
};
openModal = () => {
const { page, sortBy, sortDir } = this.state;
this.fetchData(page, sortBy, sortDir);
this.setState({
showFoodDescriptionsModal: true,
});
};
closeModal = () => {
this.setState({
showFoodDescriptionsModal: false,
});
};
changePage = (page) => {
const { sortBy, sortDir } = this.state;
this.setState({
page,
dataLoaded: false
}, () => this.fetchData(page, sortBy, sortDir));
};
changeSortBy = (sortBy) => {
/* eslint-disable-next-line prefer-destructuring */
let sortDir = this.state.sortDir;
if (sortBy === this.state.sortBy) {
sortDir = (this.state.sortDir === 'desc') ? 'asc' : 'desc';
}
this.setState({
sortBy,
sortDir,
dataLoaded: false,
}, () => this.fetchData(this.state.page, sortBy, sortDir));
};
renderEmptyState() {
const { classes } = this.props;
return (
<Grid container alignItems="center" justify="center" className={classes.progressContainer}>
<Typography className={classes.noCoinsText}>No configurations found</Typography>
</Grid>
);
}
renderLoader() {
const { classes } = this.props;
return (
<Grid container alignItems="center" justify="center" className={classes.progressContainer}>
<PulseLoader size={6} color="#52B0B0" loading />
</Grid>
);
}
renderTable() {
const { data, page } = this.state;
return (
<StrategiesTable
strategies={data}
onClickCopy={this.applyConfig}
page={page}
changePage={this.changePage}
sortBy={this.changeSortBy} />
);
}
render() {
const {
classes, userFeatures, botConfig, theme
} = this.props;
const { showFoodDescriptionsModal, dataLoaded } = this.state;
if (!botConfig) {
return null;
}
return (
<Fragment>
<div className={classes.smartSuggestContainer}>
<Button
name="discoverConfigs"
variant={theme.breakpoints.down(600) ? '' : 'outlined'}
color="primary"
size="small"
disabled={!userFeatures['smart_suggest_backtests'.toUpperCase()] || botConfig.status.toLowerCase() === STATUSES.RUNNING}
onClick={this.openModal}>
Food Buy
</Button>
</div>
</Fragment>
);
}
}
function mapStateToProps(state) {
return {
userFeatures: state.global.paywall.features,
};
}
function mapDispatchToProps(dispatcher) {
return {
actions: {
...bindActionCreators({
showNotification,
}, dispatcher)
}
};
}
connect(mapStateToProps, mapDispatchToProps)(withTheme()(withStyles(styles)(FoodDescriptions)));
解决方案
为什么不使用 useMediaQuery 创建一个功能组件并返回响应式 Button ?
推荐阅读
- ios - UISegmentedControl iOS 13 一起改变 UIControlStateSelected 和 UIControlStateHighlighted 的颜色
- matlab - 三维最小均方
- aix - Websphere Liberty Profile CPU 100% AIX 7.1 TL3
- spring-boot - 存储库上的奇怪 Spring Boot @Autowired 错误不是由于错误的项目结构或缺少注释
- r - 通过提取相似的列名跨列应用函数
- numpy - 操作数不能用形状广播 (19,)(0,) -- KNN
- r - 我们如何使用 R 中的闭包为 5 个不同的玩家构建一个计时器
- angular - 带角度的数据存储在客户端
- python - DRF 验证器在唯一性检查时不返回 false
- windows - 如何使用 terraform 上的选美来建立 SSH 连接以提供文件?