reactjs - 将 React-Redux 与 connect() 和 {...this.props} 一起使用

标签 reactjs nested redux react-redux

当我想从其他组件调用容器中的操作时,我无法弄清楚如何制定正确的解决方案,顺便说一句,我想使用扩展运算符,因为我需要在组件中传递太多参数并且不这样做不想描述所有这些。

我知道我可以通过 props 从 redux store 传递所有 props,就像菜单中的这个例子,但是我的组件太嵌套了,我必须在嵌套的八个组件中发送 props

render() {

        return (
            <div className="wrapper">
                <Menu {...this.props} />
            </div>
        );

    }

}

const mapStateToProps = reduxStore => (
    {
        app: reduxStore.app
    }),

    mapDispatchToProps = dispatch => ({appActions: bindActionCreators(appActions, dispatch)});

export default connect(mapStateToProps, mapDispatchToProps)(App);

因此,我决定将嵌套组件与 redux 存储连接起来,因为我需要使用主容器组件中的存储和操作来使用嵌套组件。但这个解决方案不起作用,因为我对嵌套组件使用了扩展运算符。

render() {

        return <Link activeClassName='active' onClick={this.props.appActions.closeMenu} {...this.props} />;

    }

使用扩展运算符非常重要,因为组件从其父组件获取了太多不同的参数,如果我不使用 {...this.props},我必须这样写:

render() {

        const { to, onlyActiveOnIndex, className, specialIcons } = this.props;

        return <Link activeClassName='active' onClick={this.props.appActions.closeMenu} to={to} specialIcons={specialIcons} onlyActiveOnIndex={onlyActiveOnIndex} className={className} >{this.props.children}</Link>;

    }

而且,我必须连接到常见的 redux 存储,当我连接时,会发生错误,因为我的组件使用 {...this.props} 并且它获取所有 Prop ,包括来自容器和组件的操作不知道该怎么处理它们。我找到了这个问题的一个解决方案,但我不确定它是否是正确的变体。我使用扩展运算符克隆 props,但从公共(public)存储中删除包含新函数(操作)的属性。

render() {

        let oldProps = {...this.props};
        delete oldProps.appActions;
        delete oldProps.app;

        return <Link activeClassName='active' onClick={this.props.appActions.closeMenu} {...oldProps} >{this.props.children}</Link>;

    }

}

const mapState = reduxStore => ({app: reduxStore.app}),
    mapDispatchToProps = dispatch => ({appActions: bindActionCreators(appActions, dispatch)});

export default connect(mapState, mapDispatchToProps)(NavLink);

我猜我不理解react-redux中的一些基本和全局的东西,或者我使用了不好的做法。也许我应该在 React 中使用更高阶的组件?但现在我不知道如何让它变得更好。

最佳答案

这是一个功能示例。我为个人项目制作了它。为了示例的目的,我删除了无用的代码。 您可能想要得到的是 eslint,它会向您显示人们在编码时犯的基本错误。

例如,它会说您已经声明了您的 PropTypes。在你的代码中,哪里说了什么应用程序?当然它来自 reduxStore.app 但它是什么样的 PropTypes ?

此外,您不应将所有 reduxStore 状态链接到您的组件。您应该只导入您真正需要的内容。在我的示例中,我仅从 state.app.users 导入 users。如果我有更多,或者想要 reducer 状态的所有元素,我将单独导入所有元素,然后声明如下 Prop :

 Home.propTypes = {
        users: PropTypes.object.isRequired,
        actions: {
            load: PropTypes.func.isRequired,
        },
    };

因为 JavaScript 不是类型化语言,所以上面的 PropTypes 可以帮助您进行类型化验证。您还可以看到 Prop actions,其中包含您在案例中的 AppActions 中导入的所有函数。

要了解如何使用操作中的函数,请查看我的 componentWillMount()

    import React, { Component, PropTypes } from 'react';
    import { ListView} from 'react-native';
    import { connect } from 'react-redux';
    import { bindActionCreators } from 'redux';

    import * as app from '../../actions/appActions';

    const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });

    class Home extends Component {

        constructor(props) {
            super(props);
            this.state = {
                dataSource: ds.cloneWithRows(props.users.toJS()),
            };
        }

        componentWillMount() {
            this.props.actions.load();
        }

        componentWillReceiveProps(nextProps) {
            if (this.props.users !== nextProps.users) {
                this.setState({
                    dataSource: ds.cloneWithRows(nextProps.users),
                });
            }
        }

        render() {
            return (
                  <ListView
                      dataSource={this.state.dataSource}
                      enableEmptySections
                      renderRow={
                          (rowData) => <User haveLunch={rowData.haveLunch} name={rowData.name} />
                      }
                  />
            );
        }
    }

    Home.propTypes = {
        users: PropTypes.object.isRequired,
        actions: {
            load: PropTypes.func.isRequired,
        },
    };

    function mapStateToProps(state) {
        return {
            users: state.app.users,
        };
    }

    function mapDispatchToProps(dispatch) {
        return {
            actions: bindActionCreators(app, dispatch),
        };
    }

export default connect(mapStateToProps, mapDispatchToProps)(Home);

希望这对你有帮助;)

关于reactjs - 将 React-Redux 与 connect() 和 {...this.props} 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40289164/

相关文章:

javascript - Expo AV : 'if' video has finished, 返回开始

javascript - React - 组件或一种拥有类似于 Chrome/Firefox JS 控制台的控制台的方法

javascript - IntersectionObserverAPI 当所有元素都不可见时返回默认状态

json - 如何解析嵌套的JSON字典( map )

java - 封闭类成员的内部类访问

reactjs - react redux,thunk 完成的事件过早发生

javascript - Admin-on-rest 是否提供日期范围选择器

java - NoSuchMethodError : org. springframework.data.util.TypeInformation.isSubTypeOf(Ljava/lang/Class;)Z

javascript - 在中间件中调度 redux 操作会导致意外行为

reactjs - 如何将 Mapbox GL 与 React 和 Redux 结合使用?