我想在 React-MUI 中有一个对话框作为一个单独的组件
I want to have a dialog as a separate component in React-MUI
我正在使用 React 和 MUI (v5)
我想在我的组件中显示一个对话框,但我希望这个对话框作为一个单独的组件,例如:
function MyComponent() {
const [ openDialog, setOpenDialog ] = useState(false);
const handleOpenDialog = () => {
setOpenDialog(true);
};
return (
<React.Fragment>
<Button variant="contained" size="medium" onClick={handleOpenDialog}>
Open Dialog
</Button>
<CreateCategory openDialog={openDialog} />
<Box>
...
</Box>
</React.Fragment>
);
}
对话框如下:
export default function CreateCategory(props) {
const [openDialog, setOpenDialog] = useState(props.openDialog);
const [newCategoryName, setNewCategoryName] = useState("");
const handleDialogClose = () => {
setOpenDialog(false);
};
const handleAddCategory = (categoryName) => {
...
};
const handleCategoryNameChange = (e) => {
setNewCategoryName(e.target.value);
};
return (
<React.Fragment>
<Dialog
fullWidth
maxWidth={"sm"}
open={openDialog}
onClose={handleDialogClose}
>
<DialogTitle>Create Video Category</DialogTitle>
<DialogContent>
<TextField
...
/>
</DialogContent>
<DialogActions>
<Button ...>
Add Category
</Button>
<Button variant="outlined" onClick={handleDialogClose}>
Close
</Button>
</DialogActions>
</Dialog>
</React.Fragment>
);
}
但它不起作用,我想在另一个组件中重用该对话框
我在代码沙盒中有它https://codesandbox.io/s/quizzical-merkle-ivquu?file=/src/App.js
拉斐尔
无缘无故地将 props 复制到 state 是一种反模式,它会导致您的问题。
您有 两个 状态,称为 openDialog
(一个在父级中,一个在子级中),并期望它们像相同一样运行.
要更正此问题,请直接在您的组件中使用 props.openDialog
,并将 setter 函数也作为 prop 传递下去。然后删除本地状态版本,因为它不会再被使用。
// Pass the setter as well
<CreateCategory openDialog={openDialog} setOpenDialog={setOpenDialog} />
const handleDialogClose = () => {
props.setOpenDialog(false); // Use the prop.
};
<Dialog
fullWidth
maxWidth={"sm"}
open={props.openDialog} // Use value directly here
onClose={handleDialogClose}
>
万一这也是以下代码段(您无论如何都应该删除)中的混淆源:
const [openDialog, setOpenDialog] = useState(props.openDialog);
props.openDialog
仅在第一次渲染时使用一次 来初始化状态。将来任何时候 prop 发生变化,状态 都不会 改变以匹配它。这是一个初始值。
我正在使用 React 和 MUI (v5)
我想在我的组件中显示一个对话框,但我希望这个对话框作为一个单独的组件,例如:
function MyComponent() {
const [ openDialog, setOpenDialog ] = useState(false);
const handleOpenDialog = () => {
setOpenDialog(true);
};
return (
<React.Fragment>
<Button variant="contained" size="medium" onClick={handleOpenDialog}>
Open Dialog
</Button>
<CreateCategory openDialog={openDialog} />
<Box>
...
</Box>
</React.Fragment>
);
}
对话框如下:
export default function CreateCategory(props) {
const [openDialog, setOpenDialog] = useState(props.openDialog);
const [newCategoryName, setNewCategoryName] = useState("");
const handleDialogClose = () => {
setOpenDialog(false);
};
const handleAddCategory = (categoryName) => {
...
};
const handleCategoryNameChange = (e) => {
setNewCategoryName(e.target.value);
};
return (
<React.Fragment>
<Dialog
fullWidth
maxWidth={"sm"}
open={openDialog}
onClose={handleDialogClose}
>
<DialogTitle>Create Video Category</DialogTitle>
<DialogContent>
<TextField
...
/>
</DialogContent>
<DialogActions>
<Button ...>
Add Category
</Button>
<Button variant="outlined" onClick={handleDialogClose}>
Close
</Button>
</DialogActions>
</Dialog>
</React.Fragment>
);
}
但它不起作用,我想在另一个组件中重用该对话框
我在代码沙盒中有它https://codesandbox.io/s/quizzical-merkle-ivquu?file=/src/App.js
拉斐尔
无缘无故地将 props 复制到 state 是一种反模式,它会导致您的问题。
您有 两个 状态,称为 openDialog
(一个在父级中,一个在子级中),并期望它们像相同一样运行.
要更正此问题,请直接在您的组件中使用 props.openDialog
,并将 setter 函数也作为 prop 传递下去。然后删除本地状态版本,因为它不会再被使用。
// Pass the setter as well
<CreateCategory openDialog={openDialog} setOpenDialog={setOpenDialog} />
const handleDialogClose = () => {
props.setOpenDialog(false); // Use the prop.
};
<Dialog
fullWidth
maxWidth={"sm"}
open={props.openDialog} // Use value directly here
onClose={handleDialogClose}
>
万一这也是以下代码段(您无论如何都应该删除)中的混淆源:
const [openDialog, setOpenDialog] = useState(props.openDialog);
props.openDialog
仅在第一次渲染时使用一次 来初始化状态。将来任何时候 prop 发生变化,状态 都不会 改变以匹配它。这是一个初始值。