The site has a window (done with Dialog mui
) that opens to get information (Device with id {} is at the user's) .
There is a static text in this window (which is always present) and I want to finish off the text (in my case ID), which will change depending on the data.
My data is stored in the selectedItem
object. But here the problem is, when the window (Dialog mui
) is closed, then selectedItem === null
.
Please tell me how to get ID correctly
export default function Table() {
const records = useRecords(firestore)
const [selectedItem, setSelectedItem] = useState();
const handleClose = () => {
setSelectedItem(null);
}
return (
<div>
<Dialog open={!!selectedItem} onClose={handleClose}>
Device with id {} is at the user's
</Dialog>
{records.map((record) =>
<TableCell record={record}
onDeleteButtonPress={() => setSelectedItem(record)}
key={record.id} />)}
</div>
)
}
CodePudding user response:
You can use another state to open/close that dialog accordingly. You can check the below code with my comments.
export default function Table() {
const records = useRecords(firestore)
const [selectedItem, setSelectedItem] = useState();
//the new dialog state
const [isDialogOpened, setIsDialogOpened] = useState(false);
const handleClose = () => {
//close the dialog manually with a state update
setIsDialogOpened(false);
}
//when `selectedItem` is true, we will open the dialog
React.useEffect(() => {
if(selectedItem) {
setIsDialogOpened(true)
}
}, [selectedItem])
return (
<div>
<Dialog open={isDialogOpened} onClose={handleClose}>
Device with id {} is at the user's
</Dialog>
{records.map((record) =>
<TableCell record={record}
onDeleteButtonPress={() => setSelectedItem(record)}
key={record.id} />)}
</div>
)
}
If you don't want to have side-effects from useEffect
, you can update isDialogOpened
state in onDeleteButtonPress
event as well.
export default function Table() {
const records = useRecords(firestore)
const [selectedItem, setSelectedItem] = useState();
//the new dialog state
const [isDialogOpened, setIsDialogOpened] = useState(false);
const handleClose = () => {
//close the dialog manually with a state update
setIsDialogOpened(false);
}
return (
<div>
<Dialog open={isDialogOpened} onClose={handleClose}>
Device with id {} is at the user's
</Dialog>
{records.map((record) =>
<TableCell record={record}
onDeleteButtonPress={() => {
setSelectedItem(record);
setIsDialogOpened(true); //open the dialog when `onDeleteButtonPress`
}}
key={record.id} />)}
</div>
)
}
CodePudding user response:
One option is to use optional chaining (?.
) to avoid trying to read id
when selectedItem
is undefined
/null
:
<Dialog open={!!selectedItem} onClose={handleClose}>
Device with id {selectedItem?.id} is at the user's
</Dialog>
The problem is that React still evaluates its children even if the component they sit within (in this case Dialog
) doesn't get rendered. That's because the above JSX code transpiles into the following React.createElement()
function call:
React.createElement(Dialog, {
open: !!selectedItem,
onClose: handleClose
}, "Device with id ", selectedItem?.id, " is at the user's");
So each of the arguments need to be evaluated before createElement()
is called, meaning that if you were to use selectedItem.id
when selectedItem
is null
/undefined
, JS would throw an error when this is evaluated. With optional chaining however, when selectedItem?.id
is evaluated we get back undefined
instead of JS throwing an error.
CodePudding user response:
You seem to be setting it to null on close? Just remove the
setSelectedItem(null)
from the handle close. This should keep the state after closing the dialog.