我正努力在我的React + Redux + ReactRouter4应用程序中使用react-modal。
我有一个MainLayout容器和一个Home容器。
只有在渲染主容器时才会使用模态,因此我在主容器中有ReactModal的逻辑。我可以像这样轻松地从Home Container打开模态:
<button onClick={this.openModal}>Open Modal</button>
问题是MainLayout容器有一个导航,也需要能够打开模态,但很明显,this.openModal在那里不存在...我如何允许MainLayout容器打开Home容器中的模态?
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
modalIsOpen: false
};
this.openModal = this.openModal.bind(this);
this.closeModal = this.closeModal.bind(this);
}
openModal() {
this.setState({modalIsOpen: true});
}
closeModal() {
this.setState({modalIsOpen: false});
}
render() {
return (
<div>
....
<button onClick={this.openModal}>Open Modal</button>
<Modal
isOpen={this.state.modalIsOpen}
onAfterOpen={this.afterOpenModal}
onRequestClose={this.closeModal}
style={modalCustomStyles}
contentLabel="Example Modal"
>
<h2 ref={subtitle => this.subtitle = subtitle}>Hi</h2>
<button onClick={this.closeModal}>close</button>
<div>I am a modal</div>
</Modal>
</div>
)
};
};
App.jsx
const WithMainLayout = ({component: Component, ...more}) => {
return <Route {...more} render={props => {
return (
<MainLayout {...props}>
<Component {...props} />
</MainLayout>
);
}}/>;
};
....
<WithMainLayout exact path="/" component={Home} />
答案 0 :(得分:1)
我要做的只是将modalOpenState移动到redux而不是将其保持在本地状态。你的初始状态就是这样。
export default {
modalIsOpen: false
};
然后编写一个动作来切换商店中的模态状态。
export function toggleQuestionModal(isOpen) {
return { type: types.TOGGLE_QUESTION_MODAL, payload: isOpen };
}
你对模态的表达部分应该是这样的。
import React, { Component, PropTypes } from 'react';
import Modal from 'react-modal';
const QuestionModal = ({ modalIsOpen, openModal, closeModal, afterOpenModal }) => {
const customStyles = {
overlay: {
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.75)'
},
content: {
top: '50%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
height: '50%',
width: '80%',
transform: 'translate(-50%, -50%)'
}
};
return (
<div>
<button onClick={openModal}>Open Modal</button>
<Modal
isOpen={modalIsOpen}
onAfterOpen={afterOpenModal}
onRequestClose={closeModal}
style={customStyles}
contentLabel="Create A Question"
role="dialog"
>
<h2>Hello</h2>
<button onClick={closeModal}>close</button>
<div>I am a modal</div>
<form>
<input />
<button>tab navigation</button>
<button>stays</button>
<button>inside</button>
<button>the modal</button>
</form>
</Modal>
</div>
);
};
QuestionModal.propTypes = {
modalIsOpen: PropTypes.bool.isRequired,
openModal: PropTypes.func.isRequired,
closeModal: PropTypes.func.isRequired,
afterOpenModal: PropTypes.func.isRequired
};
export default QuestionModal;
最后,这是模态的容器组件。
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { toggleQuestionModal, toggleConfirmation } from '../actions/questionActions';
import QuestionModal from '../components/questionModal';
class QuestionPage extends Component {
constructor(props, context) {
super(props, context);
this.openModal = this.openModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.afterOpenModal = this.afterOpenModal.bind(this);
}
openModal() {
this.props.toggleQuestionModal(true);
}
afterOpenModal() {
// references are now sync'd and can be accessed.
// this.subtitle.style.color = '#f00';
}
closeModal() {
this.props.toggleConfirmation(true);
}
render() {
const { modalIsOpen } = this.props;
return (
<div>
<QuestionModal modalIsOpen={modalIsOpen} openModal={this.openModal} closeModal={this.closeModal}
afterOpenModal={this.afterOpenModal} />
</div>
);
}
}
QuestionPage.propTypes = {
modalIsOpen: PropTypes.bool.isRequired,
toggleQuestionModal: PropTypes.func.isRequired,
};
function mapStateToProps(state, ownProps) {
return {
modalIsOpen: state.question.modalIsOpen
};
}
function mapDispatchToProps(dispatch) {
return {
toggleQuestionModal: bindActionCreators(toggleQuestionModal, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(QuestionPage);
如果要从任何组件打开模态,只需使用true值调用toggleQuestionModal
操作。这将改变状态并渲染模态。 Redux建议将所有内容保持在状态。我这样做。不要把事情保持在当地。保持一切状态使您可以更轻松地使用工具进行时间旅行调试。您可以找到示例实现here。希望这可以帮助。快乐的编码!