【发布时间】:2021-01-16 04:51:00
【问题描述】:
我使用 Material-ui(和 Typescript)在 React 中制作了一个自定义的 Snackbar 组件。我很难理解传播运算符和等待的工作方式。 (此处示例:https://codesandbox.io/s/gifted-hopper-tkkpi?file=/src/App.tsx:1311-1380)
完整代码:
import React, { FunctionComponent, useEffect } from "react";
import Button from "@material-ui/core/Button";
import Snackbar from "@material-ui/core/Snackbar";
import { Color } from "@material-ui/lab";
import { Alert } from "@material-ui/lab";
interface SnackbarModel {
open: boolean;
severity?: Color;
message: string;
}
const CustomSnackbar: FunctionComponent<SnackbarModel> = (props) => {
const [opened, setOpened] = React.useState(false);
useEffect(() => {
if (props.open) {
setOpened(true);
}
}, [props.open]);
const handleClose = (event: React.ChangeEvent<object>, reason: string) => {
if (reason === "clickaway") {
return;
}
setOpened(false);
};
return (
<div>
<Snackbar
open={opened}
autoHideDuration={2000}
onClose={handleClose}
anchorOrigin={{ vertical: "top", horizontal: "center" }}
>
<Alert severity={props.severity}>{props.message}</Alert>
</Snackbar>
</div>
);
};
export default function App() {
const [snackbar, setSnackbar] = React.useState<SnackbarModel>({
open: false,
message: ""
});
async function handleClick() {
await fetch(Stuff...)
// Working as desired
//setSnackbar({open: true, severity: "success", message: "Snackbar"});
//setSnackbar({open: false, severity: "success", message: "Snackbar"});
// Somehow not working
setSnackbar({ open: true, severity: "success", message: "Snackbar" });
setSnackbar({ ...snackbar, open: false });
}
return (
<div>
<CustomSnackbar
open={snackbar.open}
message={snackbar.message}
severity={snackbar.severity}
/>
<Button variant="contained" onClick={handleClick}>
Snackbar
</Button>
</div>
);
}
我触发 Snackbar 打开
const [snackbar, setSnackbar] = React.useState<SnackbarModel>({
open: false,
message: ""
});
async function handleClick() {
await fetch(Stuff)
setSnackbar({open: true, severity: "success", message: "Snackbar"})
setSnackbar({open: false, severity: "success", message: "Snackbar"});
}
Snackbar 会在设定的时间后自动关闭。 “open”只触发Snackbar,不控制Snackbar的setOpen-state。
现在我尝试了:
setSnackbar({ open: true, severity: "success", message: "Snackbar" });
console.log(snackbar); //gives you: Object {open: false, message: ""}
setSnackbar({ ...snackbar, open: false });
这成功触发了 Snackbar,但消息/文本丢失了。
问题1:“...snackbar”不应该还保存“message: 'Snackbar'”吗?
由于某种原因,如果我不使用“await fetch(Stuff...)”,我还必须使函数异步并等待第一个“setSnackbar”:
async function handleClick() {
//working as desired
await setSnackbar({open: true, severity: "success", message: "Snackbar"});
setSnackbar({open: false, severity: "success", message: "Snackbar"});
// OR
//not working as desired
await setSnackbar({ open: true, severity: "success", message: "Snackbar" });
setSnackbar({ ...snackbar, open: false });
}
如果您首先等待另一行代码,显然不需要“setSnackbar”上的等待。在我的用例中,这是可行的:
async function handleClick() {
await fetch(Stuff...)
setSnackbar({open: true, severity: "success", message: "Snackbar"});
setSnackbar({open: false, severity: "success", message: "Snackbar"});
}
问题 2:有人可以解释为什么需要/不需要等待吗?
【问题讨论】:
标签: javascript html reactjs typescript material-ui