使用mapStateToProps连接到redux存储的确认模式会给出错误

时间:2017-05-14 03:57:04

标签: javascript reactjs modal-dialog redux react-jsx

我有一个模态组件。单击模态的关闭按钮时,我需要显示确认模式。它有,没有选择。 此确认组件已连接到Redux商店。

在我使用mapStateToProps将确认组件连接到商店之前,一切正常。在那之后,我才开始收到此错误。

错误:无法在“Connect(_class)”的上下文或道具中找到“store”。将根组件包装在a中,或者将“store”显式传递为“Connect(_class)”的prop。     at invariant(bundle.js:21701)

我附上了下面的图片。

enter image description here

这是我的确认模式。

import React, { Component, PropTypes } from 'react';
import AriaModal from 'react-aria-modal';
import { confirm } from '../util/confirm';
import { confirmable } from 'react-confirm';

class Confirmation extends Component {
  constructor(props) {
    super(props);
    this.getApplicationNode = this.getApplicationNode.bind(this);
  }

  getApplicationNode = () => {
    return document.getElementById('application');
  }

  render() {
    console.log("rendering confirmation....");
    const {
     okLabbel = 'OK',
     cancelLabel = 'Cancel',
     title,
     confirmation,
     show,
     proceed,
     dismiss,
     cancel,
     enableEscape = true,
   } = this.props;

    const modal =
        <AriaModal
          titleText="demo one"
          onExit={this.deactivateModal}
          mounted={this.props.modalActive}
          initialFocus="#demo-one-deactivate"
          getApplicationNode={this.getApplicationNode}
          underlayStyle={{ paddingTop: '2em' }}
        >
          <div id="test-modal" className="background">
            <div className='model-title'>
              <h3 className='pe-title'>{title}</h3>
            </div>
            <div className="modal-body">
              {confirmation}
            </div>
            <footer className="modal-footer">
              <button className="btn btn-info" onClick={cancel}>{cancelLabel}</button>
              <button className='btn btn-danger' onClick={proceed}>{okLabbel}</button>
            </footer>
          </div>
        </AriaModal>;

    return (
      <div>
        {modal}
      </div>
    );
  }

}

Confirmation.propTypes = {
  okLabbel: PropTypes.string,
  cancelLabel: PropTypes.string,
  title: PropTypes.string,
  confirmation: PropTypes.string,
  show: PropTypes.bool,
  proceed: PropTypes.func,     // called when ok button is clicked.
  cancel: PropTypes.func,      // called when cancel button is clicked.
  dismiss: PropTypes.func,     // called when backdrop is clicked or escaped.
  enableEscape: PropTypes.bool,
}

export default confirmable(Confirmation);

这是我将它连接到容器组件中的商店的方式。

import { connect } from 'react-redux';
import Confirmation from '../components/Confirmation';

const mapStateToProps = (state) => {
  console.log("Calling mapStateToProps here!" + state.confirmation.modalActive);
  return { modalActive: state.confirmation.modalActive };
}

export default connect(mapStateToProps)(Confirmation);

您可能会在控制台中看到将可见性设置为true的初始操作正常,并且操作会像这样记录在控制台中。

{type: ON_CONFIRM, payload: true}

这个mapStateToProps有什么问题?

您可以找到项目代码here

为什么我收到此错误。这里出了什么问题?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

问题出在react-confirm库中。它将您的确认模型呈现在其自己的组件树中,而不是在您的应用程序的组件树中。如果查看其source code,您可以看到它在内部使用ReactDOM.render来创建新的组件树。就像你在同一页面上有两个React应用程序一样。

react-redux的

mapStateToProps使用React上下文来访问商店。但是,当连接的确认组件在不同的组件树中呈现时,连接HoC无法通过上下文访问redux存储。

最简单的解决方案是找到另一个没有这个问题的库。但是,您也可以使用HoC手动将context注入到已连接的确认中。

这是一个HoC,您可以使用它将上下文注入组件:

function withContext(WrappedComponent, context){

  class ContextProvider extends React.Component {
    getChildContext() {
      return context;
    }

    render() {
      return <WrappedComponent {...this.props} />
    }
  }

  ContextProvider.childContextTypes = {};
  Object.keys(context).forEach(key => {
    ContextProvider.childContextTypes[key] = React.PropTypes.any.isRequired; 
  });

  return ContextProvider;
}

假设您在组件调用页面中呈现已连接的确认组件。然后你可以使用上面的HoC注入上下文。

class Page extends React.Component {

  //......

  static contextTypes = {
    store: React.PropTypes.object.isRequired
  }

  render(){

    const ConfirmationWithContext = withContext(ConnectedConfirmation, this.context);

    return (
      //.....
      <ConfirmationWithContext/> // with your props
      //.....
    );
  }

}