gpt4 book ai didi

reactjs - react 高阶组件在 typescript 中不起作用

转载 作者:行者123 更新时间:2023-12-05 05:02:05 24 4
gpt4 key购买 nike

问题

我正在尝试将 HOC 从 javascript 提升到 typescript。 HOC 在使用它的组件中添加了一个确认对话框,提供了一个 showConfirmationDialog 属性,它在被调用时显示对话框并在点击确认时运行回调。

代码编译正常,但是当我在浏览器中打开应用程序时,出现错误“无效的 Hook 调用。 Hook 只能在函数组件的主体内部调用。”

该代码在 javascript 中运行良好。我无法理解该错误,并且我已按照所有建议的步骤进行操作,但没有任何解决方法。

代码

ConfirmationDialog/index.tsx

type ExtraProps = {
showConfirmationDialog: (params: RequiredParameters) => void
}

type ConfirmationCallback = () => void

interface RequiredParameters {
dialogTitle: string,
dialogContent: string,
confirmationButtonText: string,
onConfirm: ConfirmationCallback
}

const WithConfirmationDialog = <P extends ExtraProps>(Component: React.ComponentType<P>) => {

const [open, setOpen] = useState(false)
const [title, setTitle] = useState('')
const [content, setContent] = useState('')
const [confirmationButtonText, setConfirmationButtonText] = useState('')
const [onConfirm, setOnConfirm] = useState<ConfirmationCallback>()

const handleShow = (params: RequiredParameters) => {
setTitle(params.dialogTitle)
setContent(params.dialogContent)
setConfirmationButtonText(params.confirmationButtonText)
setOnConfirm(params.onConfirm)
setOpen(true)
}

const handleConfirm = () => {
if (onConfirm) {
onConfirm()
}
setOpen(false)
}

const handleClose = () => {
setOpen(false)
}

const ComponentWithConfirmationDialog = (props: P) => (
<>
<Dialog
open={open}
onClose={handleClose}
>
<DialogTitle>{title}</DialogTitle>
<DialogContent>
<DialogContentText>{content} </DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleConfirm} color="primary">
{confirmationButtonText}
</Button>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
</DialogActions>
</Dialog>
<Component {...props} showConfirmationDialog={handleShow} />
</>
)

return ComponentWithConfirmationDialog
}

export default WithConfirmationDialog

单击另一个组件中的按钮后使用代码的示例:

import withConfirmationDialog from '../ConfirmationDialog'

const MyComponent = (props) => {
const classes = useStyles();

const handleDeleteBooking = () => {
// ...make api calls and handle results...
};

// left out everything else for brevity

return (
<Fab // material-ui
className={classes.deleteButton}
aria-label="delete"
onClick={(e) => {
props.showConfirmationDialog({
dialogTitle: "Delete Booking",
dialogContent: "Are you sure you want to delete this booking?",
confirmationButtonText: "Delete",
onConfirm: handleDeleteBooking,
});
}}
>
<DeleteIcon /> // material-ui
</Fab>
);
};

export default withConfirmationDialog(MyComponent)

附加信息

我用来构建这个的主要指南可以是 found here .运行 npm start 时编译正常,错误永远不会显示在终端中。我只在我的浏览器中看到“无效 Hook 调用”消息,以及指向我第一次在我的 HOC 中使用 useState(false 的堆栈跟踪。

如有任何帮助,我们将不胜感激!

最佳答案

这里的问题是您的 HOC 正在函数组件 ComponentWithConfirmationDialog 之外调用 Hook 。所有钩子(Hook)都必须在组件内部调用,而不是外部。您的 HOC 函数本身不是组件。

为了解决这个问题,您需要将 ComponentWithConfirmationDialog 上方的所有内容移动到其中,例如:

const WithConfirmationDialog = <P extends ExtraProps>(Component: React.ComponentType<P>) => {

const ComponentWithConfirmationDialog = (props: P) => {
const [open, setOpen] = useState(false)
const [title, setTitle] = useState('')
const [content, setContent] = useState('')
const [confirmationButtonText, setConfirmationButtonText] = useState('')
const [onConfirm, setOnConfirm] = useState<ConfirmationCallback>()

const handleShow = (params: RequiredParameters) => {
setTitle(params.dialogTitle)
setContent(params.dialogContent)
setConfirmationButtonText(params.confirmationButtonText)
setOnConfirm(params.onConfirm)
setOpen(true)
}

const handleConfirm = () => {
if (onConfirm) {
onConfirm()
}
setOpen(false)
}

const handleClose = () => {
setOpen(false)
}

return (
<>
<Dialog
open={open}
onClose={handleClose}
>
<DialogTitle>{title}</DialogTitle>
<DialogContent>
<DialogContentText>{content} </DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleConfirm} color="primary">
{confirmationButtonText}
</Button>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
</DialogActions>
</Dialog>
<Component {...props} showConfirmationDialog={handleShow} />
</>
)
}
return ComponentWithConfirmationDialog
}

export default WithConfirmationDialog

关于reactjs - react 高阶组件在 typescript 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62392542/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com