通过在应用程序组件上方调用它,实现了一个可在我的应用程序中的任何组件中重用的通用弹出窗口index.js
:
const handleClickBtn = (confirmStatus,cancelStatus) => {
console.log(`confirm: ${confirmStatus} ,cancel: ${cancelStatus}`);
}
root.render(
<NavigationProvider>
<PopupProvider onClickBtn={handleClickBtn}>
<Provider store={store}>
<App />
</Provider>
</PopupProvider>
</NavigationProvider>
);
我的弹出窗口(Popup.js)如下:
import { createContext, useState } from 'react';
import Modal from 'react-bootstrap/Modal'
import Button from 'react-bootstrap/Button'
import ModalHeader from 'react-bootstrap/ModalHeader'
import ModalTitle from 'react-bootstrap/ModalTitle'
import ModalBody from 'react-bootstrap/ModalBody'
import ModalFooter from 'react-bootstrap/ModalFooter'
const PopupContext = createContext();
function PopupProvider({children,onClickBtn}) {
const [show, setShow] = useState(false);
const [showCancelButton, setShowCancelButton] = useState(true);
const [size, setSize] = useState('md');
const [message, setMessage] = useState('');
const [title, setTitle] = useState('');
const [confirm, setConfirm] = useState(false);
const [confirmationText, setConfirmationText] = useState('Ok');
const [cancel, setCancelation] = useState(false);
const [cancelationText, setCancelationText] = useState('Close');
const handleClose = () => {
setShow(false);
}
const handleCancelation = () => {
//setCancelation(true); //this state may not be needed
setShow(false);
onClickBtn(false,true);
}
const handleConfirmation = () => {
//debugger;
//setConfirm(true); //this state may not be needed
setShow(false);
onClickBtn(true,false);
}
const getConfStatus = () => {
//return confirm;
}
const getCanStatus = () => {
//return cancel;
}
const changeConfText = (btnText) => {
setConfirmationText(btnText);
}
const changeCanText = (btnText) => {
setCancelationText(btnText);
}
const showPopup = (showPopupL) => {
setShow(showPopupL);
}
const popupSize = (size) => {
setSize(size);
}
const popupMessage = (msg) => {
setMessage(msg);
}
const popupTitle = (title) => {
setTitle(title);
}
const popupCancelBtn = (showButton) => {
setShowCancelButton(showButton);
}
const popupConfig = {
showPopup,
popupMessage,
popupSize,
popupTitle,
popupCancelBtn,
changeConfText,
changeCanText,
getConfStatus,
getCanStatus
};
return (
<>
<Modal
show={show}
onHide={handleClose}
size={size}
aria-labelledby="contained-modal-title-vcenter"
centered
id="Popup"
>
<Modal.Header closeButton>
{title !== '' ? <Modal.Title>{title}</Modal.Title> : ''}
</Modal.Header>
<Modal.Body>
<p>{message}</p>
</Modal.Body>
<Modal.Footer>
{showCancelButton ?
<Button variant="secondary" onClick={handleCancelation}>
{cancelationText}
</Button>
:
''
}
<Button variant="primary" onClick={handleConfirmation}>
{confirmationText}
</Button>
</Modal.Footer>
</Modal>
<PopupContext.Provider value={popupConfig}>
{children}
</PopupContext.Provider>
</>
);
}
export { PopupProvider };
export default PopupContext;
并在任何其他组件中
import usePopup from '../hooks/use-popup';
const {
showPopup,
popupMessage,
popupTitle,
changeConfText,
changeCanText,
getConfStatus,
getCanStatus
} = usePopup();
并使用此功能显示或隐藏弹出窗口,更改弹出窗口中显示的文本,按钮显示等...
const DeleteConfirm = async () => {
popupTitle(`Hike Deletion Confirmation`);
popupMessage(`Are you shure you want to delete ${hike['hikeName']}`);
changeConfText('Yes');
changeCanText('Cancel');
showPopup(true);
}
直到这里工作正常为止,我的问题现在是想在这个组件中触发弹出窗口的单击事件,以查看用户是否确认删除某些内容,但不知道如何执行此操作,因为使用 Context 只能公开值和功能。
我是否应该在顶层使用handleClickBtn,但如果用户是否单击“确认”按钮,则无法使用状态将状态传递给子组件。
任何帮助都会在这一点上有点丢失......
use-popup 是公开的钩子useContext(PopupContext)
在 Popup.js 中创建 userConfirmation 状态
根据“取消”和“确认”事件更改 userConfirmation 状态。将其与当前 popupConfig 一起传递给 PopupContext ,并在其祖先组件被 PopupProvider 包装的子组件中获取它。
弹出.js
祖先组件
子组件
您可以删除handleClickBtn 代码。
如果你想玩一下代码。
只是为了让我更清楚@Anshu 指出正确方向的解决方案:
在我的组件中:
因此,只需要查看状态 userConfirmation ,在这种情况下,这将触发对我的函数 DeleteHike 的调用,而不是尝试使触发事件传播到使此过程复杂化的组件。