React Material UI - 导出多个高阶组件
Posted
技术标签:
【中文标题】React Material UI - 导出多个高阶组件【英文标题】:React Material UI - Export multiple higher order components 【发布时间】:2018-01-24 01:44:41 【问题描述】:我一直坚持使用 redux 连接器导出 material-ui 样式。这是我的代码:
import React, Component from 'react';
import connect from 'react-redux';
import Drawer from 'material-ui/Drawer';
import withStyles from 'material-ui/styles';
import PropTypes from 'prop-types';
const mapStateToProps = state => ();
const reduxConnector = connect(mapStateToProps, null);
const styles = theme =>
console.log(theme);
return (
paper:
top: '80px',
boxShadow: theme.shadows[9]
,
);
;
class Cart extends Component
render()
const classes = this.props;
return (
<Drawer
open
docked
anchor="right"
classes= paper: classes.paper
>
<p style= width: 250 >cart</p>
</Drawer>
);
export default withStyles(styles, name: 'Cart')(Cart);
export default reduxConnector(Cart); // I want to add this
我试过了:
export default reduxConnector(withStyles(styles))(Cart); // return Uncaught TypeError: Cannot call a class as a function
export default withStyles(styles, name: 'Cart')(reduxConnector(Cart)); // return Uncaught Error: Could not find "store" in either the context or props of "Connect(Cart)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(Cart)".
有什么办法吗?
【问题讨论】:
也许是时候将 Drawer 拉出到一个展示组件中,并将“open”和“docking”作为道具传递给它?这样你就可以让你的连接组件不必处理样式......另一方面,每次使用 material-ui 组件时编写这样的包装器可能会很烦人。 【参考方案1】:试试这个
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(App));
App 是你的组件。 对我来说效果很好。
【讨论】:
太棒了!使用连接到组件的两个功能进行简单设置。两个以上最好recompose
。
以防有人不知道 mapDispatchToProps 是什么意思(比如我自己)***.com/questions/39419237/what-is-mapdispatchtoprops
是的,是的,是的!【参考方案2】:
在 material-ui 文档站点中查看它是如何处理的,特别是在 AppFrame 组件中:
export default compose(
withStyles(styles,
name: 'AppFrame',
),
withWidth(),
connect(),
)(AppFrame);
他们正在使用recompose 来执行此操作。
所以在你的情况下,它会是:
import React, Component from 'react';
import compose from 'recompose/compose';
import connect from 'react-redux';
import Drawer from 'material-ui/Drawer';
import withStyles from 'material-ui/styles';
import PropTypes from 'prop-types';
const styles = theme =>
console.log(theme);
return
paper:
top: '80px',
boxShadow: theme.shadows[9],
,
;
;
const Cart = ( classes ) =>
<Drawer open docked anchor="right" classes= paper: classes.paper >
<p style= width: 250 >cart</p>
</Drawer>;
const mapStateToProps = state => ();
export default compose(
withStyles(styles, name: 'Cart' ),
connect(mapStateToProps, null)
)(Cart);
【讨论】:
AppFrame 组件链接返回 404。@kengregory 你能更新答案以包含一个成功的链接吗? @robertjewell 完成。链接来自特定提交的版本,使其保持有效。【参考方案3】:没有recompose
或compose
:
Cart = withStyles(styles, name: 'Cart')(Cart);
export default reduxConnector(Cart);
【讨论】:
什么是reduxConnector? 看OP问题【参考方案4】:安装npm install recompose
或yarn add recompose
在您的导出部分
export default compose(
withStyles(styles,
name: 'App',
),
connect(),
)(AppFrame);
我忘了导出我的商店。
【讨论】:
【参考方案5】:这对我来说很完美
export default connect(mapStateToProps)((withStyles(styles)(ComponentNameToExport)));
【讨论】:
【参考方案6】:您可以在下面使用它。因为 withStyles 和 connect 都是高阶组件
export default withStyles(styles, name: 'Cart')(connect(mapStateToProps, mapDispatchToProps), Cart);
【讨论】:
【参考方案7】:完整的组件
import React from "react";
import makeStyles from "@material-ui/core/styles";
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import Typography from "@material-ui/core/Typography";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import withStyles from "@material-ui/core/styles";
import connect from "react-redux";
import fetchPosts from "../../store/actions/postActions";
import PropTypes from "prop-types";
const useStyles = theme => (
root:
marginLeft: 250,
marginRight: 10
,
heading:
fontSize: "1rem",
fontWeight: theme.typography.fontWeightRegular
);
class SimpleExpansionPanel extends React.Component
UNSAFE_componentWillMount()
this.props.fetchPosts();
UNSAFE_componentWillReceiveProps(nextProps)
if (nextProps.newPost)
this.props.postsa.unshift(nextProps.newPost);
render()
const classes = this.props;
const postItem = this.props.postsa.map(post => (
<ExpansionPanel key=post.id>
<ExpansionPanelSummary
expandIcon=<ExpandMoreIcon />
aria-controls="panel1a-content"
id="panel1a-header">
<Typography className=classes.heading>post.title</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>post.body</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
));
return <div className=classes.root>postItem</div>;
SimpleExpansionPanel.propTypes =
fetchPosts: PropTypes.func.isRequired,
postsa: PropTypes.array.isRequired,
newPost: PropTypes.object
;
const mapStateToProps = state => (
postsa: state.postss.items,
newPost: state.postss.item
);
export default connect(
mapStateToProps,
fetchPosts
)(withStyles(useStyles)(SimpleExpansionPanel));
【讨论】:
以上是关于React Material UI - 导出多个高阶组件的主要内容,如果未能解决你的问题,请参考以下文章
带有 Redux 的 Material UI v1 - 如何导出
material-ui 'createSvgIcon' 不是从 '@material-ui/core/utils' 导出的