【发布时间】:2021-09-05 16:46:16
【问题描述】:
我创建了一个钩子来使用确认对话框,这个钩子为组件提供属性以像这样使用它们:
const { setIsDialogOpen, dialogProps } = useConfirmDialog({
title: "Are you sure you want to delete this group?",
text: "This process is not reversible.",
buttons: {
confirm: {
onPress: onDeleteGroup,
},
},
width: "360px",
});
<ConfirmDialog {...dialogProps} />
这很好用,但我也想在需要时提供更改这些属性的选项,而无需在使用的组件中声明额外的状态,为了实现这一点,我所做的是将这些属性保存在内部的状态中钩子和这种方式提供了另一个函数来在显示对话框之前根据需要更改它们:
interface IState {
isDialogOpen: boolean;
dialogProps: TDialogProps;
}
export const useConfirmDialog = (props?: TDialogProps) => {
const [state, setState] = useState<IState>({
isDialogOpen: false,
dialogProps: {
...props,
},
});
const setIsDialogOpen = (isOpen = true) => {
setState((prevState) => ({
...prevState,
isDialogOpen: isOpen,
}));
};
// Change dialog props optionally before showing it
const showConfirmDialog = (dialogProps?: TDialogProps) => {
if (dialogProps) {
const updatedProps = { ...state.dialogProps, ...dialogProps };
setState((prevState) => ({
...prevState,
dialogProps: updatedProps,
}));
}
setIsDialogOpen(true);
};
return {
setIsDialogOpen,
showConfirmDialog,
dialogProps: {
isOpen: state.isDialogOpen,
onClose: () => setIsDialogOpen(false),
...state.dialogProps,
},
};
};
但是这里的问题是:
参数通过引用传递,因此如果我将函数传递给按钮(即 onDeleteGroup),我将保持函数更新到其最新状态,以便在其中的组 ID 发生更改时执行正确的删除。
但是当我将属性保存在一个状态中时,引用丢失了,现在我只有在开始时声明的状态的函数。
我尝试添加一个 useEffect 以在参数更改时更新钩子状态,但这会导致无限重新渲染:
useEffect(() => {
setState((prevState) => ({
...prevState,
dialogProps: props || {},
}));
}, [props]);
我知道我可以调用 showConfirmDialog 并传递函数以使用最新的函数状态更新状态,但我正在寻找一种方法来调用钩子、声明道具并且在不需要时不触摸对话框道具. 欢迎任何答案,感谢您的阅读。
【问题讨论】:
标签: reactjs typescript react-hooks arguments use-state