Estoy tratando de crear un componente de diálogo MUI con React y administrarlo desde el componente de ajuste. Aquí está mi ejemplo:
import { Dialog, DialogActions, DialogTitle, DialogContent, Button } from "@material-ui/core"; import React, {useState, useEffect} from "react"; export default function MultiNote(props) { const [useDialogOpen, setDialogOpen] = useState(false); useEffect(() => { setDialogOpen(!useDialogOpen); }, [props.open]); const handleDialogToggle = () => { setDialogOpen(!useDialogOpen); } return ( <Dialog open={useDialogOpen} onClose={handleDialogToggle} aria-labelledby="form-multinote-dialog" > <DialogTitle id="form-multinote-dialog">{props.title}</DialogTitle> <DialogContent>Test</DialogContent> <DialogActions> <Button onClick={handleDialogToggle} color="primary"> Close </Button> </DialogActions> </Dialog> ); }Aquí, estoy tratando de cambiar el estado useDialogOpen de acuerdo con la apertura del accesorio del componente. Funciona muy bien excepto en el primer render. En el primer render, abre el diálogo. Pero quiero que se cierre.
No podía entender por qué cambia.
Usé un sandbox para probar tu código. Su useEffect está alternando el useDialogOpen para que sea verdadero.
Utilicé una declaración if dentro de su useEffect para que el cuadro de diálogo no se mostrara:
useEffect(() => { if (Object.keys(props).length !== 0) { setDialogOpen(!useDialogOpen); } }, [props.open]);Esto funciona porque confirma que realmente se está pasando un accesorio al componente y no solo un objeto vacío.
Aquí hay una caja de arena con todo el código junto para que juegues:
https://codesandbox.io/s/stoic-shaw-3dszx?file=/src/App.js:259-279
La razón por la que esto sucedía era porque estabas observando un cambio de props.open que, debido a que se pasaba durante la fase de renderizado, siempre ocurría. Esto luego cambió su useDialog para que fuera verdadero y se mostraría el cuadro de diálogo.
Para responder a su primera pregunta, ¿por qué se abre el cuadro de diálogo en el primer renderizado? Lo que pasa es esto:
useDialogOpen es falso (porque se creó con useState(false) ), y el cuadro de diálogo se cierra).useEffect se ejecuta y llama a setDialogOpen(!useDialogOpen) . Como useDialogOpen actualmente es falso, es lo mismo que setDialogOpen(true)useDialogOpen como verdadero. Si desea que el estado abierto del cuadro de diálogo sea controlado por el apoyo open , puede considerar levantar el estado . Por ejemplo, deshágase de todo el estado dentro de este componente y agregue un evento onClose a los accesorios. Entonces se vería así:
function MultiNote(props) { return ( <Dialog open={props.open} onClose={props.onClose} aria-labelledby="form-multinote-dialog" > <DialogTitle id="form-multinote-dialog">{props.title}</DialogTitle> <DialogContent>Test</DialogContent> <DialogActions> <Button onClick={props.onClose} color="primary"> Close </Button> </DialogActions> </Dialog> ); }Y podría usarse así:
function App() { const [isOpen, setIsOpen] = useState(false); return <MultiNote open={isOpen} onClose={() => setIsOpen(false)} />; }Ver este codeandbox