模态在App.js中的hashRouter下呈现。当其状态为isOpen时,将显示模态。
在尝试显示带有React Redux的Modal时出现此错误。
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Check the render method of `TrapFocus`.
in ConnectFunction (at Modal.js:41)
in TrapFocus (created by ForwardRef(Modal))
in div (created by ForwardRef(Modal))
in ForwardRef(Portal) (created by ForwardRef(Modal))
in ForwardRef(Modal) (at Modal.js:35)
in Modal (created by ConnectFunction)
in ConnectFunction (created by WithStyles(undefined))
in WithStyles(undefined) (at App.js:46)
in ThemeProvider (at App.js:24)
in App (created by WithStyles(App))
in WithStyles(App) (at src/index.js:13)
in Provider (at src/index.js:12)
这是我的代码:
Modal.js
import React, { Component } from "react";
import { compose } from "redux";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { Modal as MaterialModal } from "@material-ui/core";
import { withStyles } from "@material-ui/styles";
import { closeModal } from "../store/actions/actions-ui";
import BasicModal from "./Modals/BasicModal";
const ModalTypes = {
BasicModal,
};
const styles = {
modal: {
display: "flex",
justifyContent: "center",
alignItems: "center",
},
};
class Modal extends Component {
handleCloseModal = () => {
const { dispatch, shouldCloseOnBackgroundTouch } = this.props;
if (shouldCloseOnBackgroundTouch) dispatch(closeModal());
};
render() {
const { modalType, data, isOpen, classes } = this.props;
if (!modalType) {
return null;
}
const ModalToRender = ModalTypes[modalType];
return (
<MaterialModal
disableAutoFocus
className={classes.modal}
open={isOpen}
onClose={this.handleCloseModal}
>
<ModalToRender {...data} />
</MaterialModal>
);
}
}
Modal.propTypes = {
dispatch: PropTypes.func.isRequired,
isOpen: PropTypes.bool.isRequired,
modalType: PropTypes.string,
// eslint-disable-next-line react/forbid-prop-types
data: PropTypes.object,
shouldCloseOnBackgroundTouch: PropTypes.bool.isRequired,
classes: PropTypes.objectOf(PropTypes.string).isRequired,
};
Modal.defaultProps = {
data: {},
modalType: "",
};
const mapStateToProps = (state) => ({
isOpen: state.ui.modalState.isOpen,
shouldCloseOnBackgroundTouch: state.ui.modalState.shouldCloseOnBackgroundTouch,
modalType: state.ui.modalState.modalType,
data: state.ui.modalState.data,
});
export default compose(
withStyles(styles),
connect(mapStateToProps)
)(Modal);
BasicModal.js
import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import Paper from "@material-ui/core/Paper";
import If from "../__helpers__/If";
import { closeModal } from "../../store/actions/actions-ui";
class BasicModal extends Component {
handleClose = () => {
const { dispatch } = this.props;
dispatch(closeModal());
};
render() {
const { title, text, extraBtnText, extraBtnAction } = this.props;
return (
<Paper>
<If truthy={title}>
<Typography gutterBottom variant="h4">
{title}
</Typography>
</If>
<If truthy={text}>
<Typography gutterBottom vairant="body2">
{text}
</Typography>
</If>
<Button onClick={this.handleClose}>Close</Button>
<If truthy={extraBtnAction && extraBtnText}>
<Button
onClick={() => {
extraBtnAction();
this.handleClose();
}}
>
{extraBtnText}
</Button>
</If>
</Paper>
);
}
}
BasicModal.propTypes = {
dispatch: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
text: PropTypes.string.isRequired,
extraBtnText: PropTypes.string,
extraBtnAction: PropTypes.func,
};
export default connect()(BasicModal);
我猜测问题出在我身上,试图渲染这样的组件:
<ModalToRender {...data} />
但是我似乎不明白这是怎么回事。
感谢您的帮助!
答案 0 :(得分:2)
您需要将forwardRef option in connect()用于由Material-UI的BasicModal
包装的组件(例如Modal
)。
示例:
export default connect(null, null, null, {forwardRef: true})(BasicModal);
Refs提供对React元素的DOM节点的访问。 Material-UI的TrapFocus
(由Modal
使用)uses a ref on the child传递给Modal
来管理焦点方面。
在您的情况下,传递给Modal
的孩子是connect()(BasicModal)
返回的包装器组件。默认情况下,该包装器组件是功能组件,而功能组件除非被forwardRef包装,否则不能接受引用。
forwardRef
的{{1}}选项使它使用connect
包装功能组件,以便它可以成功接受传递给包装组件的ref({{1} })。