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】:

没有recomposecompose

Cart = withStyles(styles, name: 'Cart')(Cart);
export default reduxConnector(Cart);

【讨论】:

什么是reduxConnector? 看OP问题【参考方案4】:

安装npm install recomposeyarn 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' 导出的

React / MaterialUI - 同名导入导出

React & Material-UI 分页 - 将 Material-UI 的组件连接到 React-Router

使用 React 和 Material-UI 的开源项目?

Material-UI 的 Dialog 如何允许在对话框后面进行交互?