【问题标题】:Using compose() and connect() together in React JS redux在 React JS redux 中一起使用 compose() 和 connect()
【发布时间】:2018-12-18 07:18:55
【问题描述】:

我开始使用 React JS 开发 Web 应用程序。我从主题森林买了一个主题。在主题中,他们在组件中使用了这样的 compose。

...Other code here
 Login.propTypes = {
      classes: PropTypes.shape({}).isRequired,
      width: PropTypes.string.isRequired
    };

    export default compose(withWidth(), withStyles(themeStyles, { withTheme: true }))(Login);

正如您所见,他们的代码在导出组件时最后使用了 compose。我无法修改他们的内置结构。我现在喜欢做的是我也喜欢使用 react 的连接功能。

通常使用 connect 代替 compose。现在,如果我想使用 connect 来处理应用程序的状态,如何将它与 compose 一起使用?

【问题讨论】:

  • 您可以尝试以下方法:export default compose(withWidth(), withStyles(styles, {withTheme: true}), connect(mapStateToProps, mapDispatchToProps))(Login);
  • 这是什么意思?它从哪里获得道具?使用 props 调用此组件将使用给定的 props 调用 Login 组件,然后调用 withStyles() 和 withWidth() ?这一切我还是有点迷茫

标签: reactjs redux react-redux recompose


【解决方案1】:
const enhance = compose(
    withRouter,
    withStyles(styles, 'some style'),
    connect(mapStateToProps, mapDispatchToProps),
    ....

export default enhance(MyComponent);

【讨论】:

  • 所以当这个组件被 props 调用时,它会将 props 提供给 MyComponent 然后从下到上调用 compose 中的其余函数?
【解决方案2】:
import {bindActionCreators} from 'redux';
import compose from 'recompose/compose';
import { connect } from 'react-redux';
...Other code here
function mapStateToProps(state) {
    return {
        //return state
    }
}
function mapDispatchToProps(){
    return bindActionCreators({
        //actions
    }, dispatch);
}
Login.propTypes = {
    classes: PropTypes.shape({}).isRequired,
    width: PropTypes.string.isRequired
};
export default compose(withWidth(), withStyles(styles, {withTheme: true}), connect(mapStateToProps, mapDispatchToProps))(Login);

我希望这能解决你的问题。

【讨论】:

    【解决方案3】:

    compose 并没有摆脱将函数传递给函数调用结果的模式,但它减少了它的使用。

    只有一个 HOC,使用 compose 没有任何好处:

    // withStyles, without compose
    export default withStyles(styles)(MyComponent)
    
    // withStyles, with compose
    export default compose(withStyles(styles))(MyComponent)
    
    // connect, without compose
    export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)
    
    // connect, with compose
    export default compose(connect(mapStateToProps, mapDispatchToProps))(MyComponent)
    

    请注意,在最近才流行的函数调用之后立即启动另一个函数调用,compose 仍然存在。

    有了两个 HOC,compose 会有所收获,因为括号的嵌套更少:

    // two HOCs, without compose
    export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(MyComponent))
    
    // two HOCs, with compose
    export default compose(connect(mapStateToProps, mapDispatchToProps), withStyles(styles))(MyComponent)
    

    如果您不习惯在创建后立即调用无名函数,这仍然很难理解。如果你愿意,你可以给它起个名字:

    // two HOCs, with compose
    const enhance = compose(connect(mapStateToProps, mapDispatchToProps, withStyles(styles));
    // export default enhance(MyComponent);
    

    当有多个 HOC 时,我更喜欢使用 compose,并直接使用它。我认为减少嵌套很有用,但没有必要给它一个通用名称,如 enhance

    【讨论】:

    • 优秀的答案,展示了多种方式,并且两个没有 compose 的 HOC 在一个问题上帮助了我很多!
    【解决方案4】:

    import {connect} from "react-redux";
    import {compose} from 'redux'
    
    class BookList extends Component {
        componentDidMount() {
            const {bookstoreService} = this.props;
            const data = bookstoreService.getBooks();
            this.props.booksLoaded(data);
        }
    
        render() {
            const {books} = this.props;
            return (
                <ul>
                    {books.map(book => {
                        return (
                            <li key={book.id}>
                                <BookListItem book={book}/>
                            </li>
                        );
                    })}
                </ul>
            );
        }
    }
    
    const mapStateToProps = ({books}) => {
        return {books};
    };
    const mapDispatchToProps = dispatch => {
        return {
            booksLoaded: newBooks => {
                dispatch(booksLoaded(newBooks));
            }
        };
    };
    export default compose(withBookstoreService(), connect(mapStateToProps, mapDispatchToProps))(BookList);

    【讨论】:

      【解决方案5】:

      我在使用 compose 和 Typescript 时收到以下错误: JSX element type 'App' does not have any construct or call signatures. TS2604

      我必须通过以下方式添加ComponentType 才能使其工作:

      export default compose<ComponentType>(withTranslation(), connect(mapStateToProps, mapDispatchToProps))(App);
      

      【讨论】:

        猜你喜欢
        • 2018-06-06
        • 2018-03-11
        • 2017-08-18
        • 2018-09-09
        • 2017-03-10
        • 2017-10-23
        • 1970-01-01
        • 2020-01-21
        • 2019-06-18
        相关资源
        最近更新 更多