使用 mapStateToProps 连接到 redux 存储的确认模式给出错误
Confirmation modal connecting to redux store using mapStateToProps gives an ERROR
我有一个模态组件。单击模式的关闭按钮时,我需要显示一个确认模式。它有是和没有选项。
此确认组件已连接到 Redux 存储。
一切正常,直到我使用 mapStateToProps
将确认组件连接到商店。在那之后只有我开始收到这个错误。
错误:无法在 "Connect(_class)" 的上下文或属性中找到 "store"。要么将根组件包装在 a 中,要么将 "store" 作为 prop 显式传递给 "Connect(_class)"。
在不变量 (bundle.js:21701)
我附上了下面的图片。
这是我的确认模式。
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。
为什么我会收到这个错误。这里出了什么问题?感谢任何帮助。
问题出在react-confirm库中。它在它自己的组件树中呈现您的确认模型,而不是在您的应用程序的组件树中。如果你查看它的 source code,你可以看到它在内部使用 ReactDOM.render
来创建一个新的组件树。这就像你在同一个页面上有两个 React 应用程序。
mapStateToProps
的 react-redux 使用 React context 来访问 store。但是由于connected Confirmation组件在不同的组件树中呈现,connect HoC无法通过context访问redux store。
最简单的解决办法是找到另一个没有这个问题的库。但或者,您可以使用 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;
}
假设您在组件调用页面中呈现连接的 Confirmation 组件。然后你可以像这样使用上面的 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
//.....
);
}
}
我有一个模态组件。单击模式的关闭按钮时,我需要显示一个确认模式。它有是和没有选项。 此确认组件已连接到 Redux 存储。
一切正常,直到我使用 mapStateToProps
将确认组件连接到商店。在那之后只有我开始收到这个错误。
错误:无法在 "Connect(_class)" 的上下文或属性中找到 "store"。要么将根组件包装在 a 中,要么将 "store" 作为 prop 显式传递给 "Connect(_class)"。 在不变量 (bundle.js:21701)
我附上了下面的图片。
这是我的确认模式。
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。
为什么我会收到这个错误。这里出了什么问题?感谢任何帮助。
问题出在react-confirm库中。它在它自己的组件树中呈现您的确认模型,而不是在您的应用程序的组件树中。如果你查看它的 source code,你可以看到它在内部使用 ReactDOM.render
来创建一个新的组件树。这就像你在同一个页面上有两个 React 应用程序。
mapStateToProps
的 react-redux 使用 React context 来访问 store。但是由于connected Confirmation组件在不同的组件树中呈现,connect HoC无法通过context访问redux store。
最简单的解决办法是找到另一个没有这个问题的库。但或者,您可以使用 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;
}
假设您在组件调用页面中呈现连接的 Confirmation 组件。然后你可以像这样使用上面的 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
//.....
);
}
}