He creado un componente de diálogo personalizado en Material-UI
const CustomDialog = (props) => { const [dialogOpenState, setOpen] = React.useState(props.dilaogOpenProp); return ( <> <CssBaseline /> <Dialog fullWidth onClose={() => {}} open={dialogOpenState} maxWidth="xs" sx={{ backdropFilter: "blur(5px)", }} > <DialogTitle>Example Dialog</DialogTitle> <DialogContent>Example Content Here</DialogContent> <DialogActions> <Button>ooooh.</Button> </DialogActions> </Dialog> <Box sx={{ minHeight: "100vh", background: "url(https://source.unsplash.com/random) no-repeat center center", backgroundSize: "cover", }} ></Box> </> ); } export default CustomDialog; Estoy intentando esto para administrar abrir y cerrar desde otro componente usando useState
const Minidrawer = props => { const theme = useTheme(); const { history } = props; const [open, setOpen] = React.useState(false); const [dialogOpen,setDialogueOpen] = React.useState(false) const handleDialogueOpen = () => { console.log("clicked"); setDialogueOpen(true) } return ( <Box sx={{ display: 'flex' }}> <AppBar position="fixed" open={open}> <Toolbar> <Typography variant="h6" noWrap component="div"> COMPANY NAME </Typography> <Button onClick={handleDialogueOpen}>Filter</Button> </Toolbar> </AppBar> <CustomDialog dilaogOpenProp={dialogOpen}/> </Box> ); } export default withRouter(Minidrawer); Estoy tratando de configurar dialogOpen , que se pasa en Dialog open prop value a falso usando useState , me hacen clic en la consola pero no se invoca a dilaog, también si configuro manualmente dialogOpen en useState funciona pero no al hacer clic, ¿qué está pasando? ¿aqui?
El problema es que está copiando accesorios para indicar dentro de CustomDialog . Eso significa que CustomDialog ignora los cambios en dilaogOpenProp en el padre. (Por lo general, esta no es la mejor práctica , pero hay casos extremos en los que puede tener sentido). Ya que está haciendo eso, CustomDialog solo usa el valor inicial de esa propiedad, no el valor actualizado cuando su componente principal lo cambia. Aquí hay un ejemplo más simple que demuestra eso:
const {useState} = React; const Child = (props) => { const [childValue, setChildValue] = useState(props.parentValue); return <div> <div><code>props.parentValue = {String(props.parentValue)}</code></div> <div><code>childValue = {String(childValue)}</code></div> </div>; }; const Parent = () => { const [parentValue, setParentValue] = useState(false); const toggleParentValue = () => setParentValue(v => !v); return <div> <Child parentValue={parentValue} /> <div> <button onClick={toggleParentValue}> Toggle <code>parentValue</code> </button> </div> </div>; }; ReactDOM.render(<Parent />, document.getElementById("root")); <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script> Debe almacenar el estado abierto/cerrado en el padre y hacer que el padre lo controle, o almacenar el estado abierto/cerrado en CustomDialog y hacer que CustomDialog lo controle. No puedes hacer ambas cosas.
A menudo, eso significa que el padre tenga el control, pero pasar una función al hijo que el hijo puede usar para informar al padre sobre un cambio. Por ejemplo, si necesita que CustomDialog pueda cerrarse solo (bastante común con los diálogos), puede pasarle una función que proporciona el padre que hace eso.
Si desea que el estado del componente secundario se actualice en función de la propiedad proporcionada por el componente principal, puede usar useEffect . Está pasando el accesorio a useState en el componente secundario ( React.useState(props.dilaogOpenProp) ) que solo funciona en el primer renderizado:
const [dialogOpenState, setOpen] = React.useState(props.dilaogOpenProp); useEffect(() => { // update the state every time the prop.dilaogOpenProp dependency changes setOpen(props.dilaogOpenProp); }, [props.dilaogOpenProp]);Debes mantener el estado actualizado, usa useState :
const CustomDialog = ({ dilaogOpenProp }) => { const [dialogOpenState, setOpen] = React.useState(dilaogOpenProp); useEffect(() => { setOpen(props.dialogOpenState); }, [dilaogOpenProp]) ); }También puede obtener el valor directamente de los accesorios
<Dialog open={props.dilaogOpenProp}> ... </Dialog>