【发布时间】:2021-02-20 02:37:53
【问题描述】:
我正在使用 React / Redux / Thunk / Axios 堆栈编写一个应用程序,并且对以下代码段有问题(它是一个 redux 操作):
export function rangeSelected(value) {
return (dispatch, getState) => {
let duration = Math.abs(value.end - value.start) / 3.6e6
if (duration > 4) {
dispatch(showErrorSnackbar("Error Message 1."));
return
} else if (value.start < new Date()) {
dispatch(showErrorSnackbar("Error Message 2."));
return
}
const {oidc} = getState();
return axios.get("http://localhost:8000/booking/resource/available", {
headers: {
Accept: "application/json",
Authorization: `Bearer ${oidc.user.access_token}`
},
params: {
start: moment(value.start).format('YYYY-MM-DDTHH:mm:ss'),
end: moment(value.end).format('YYYY-MM-DDTHH:mm:ss')
}
}).then(({data}) => {
if (data.length === 0) {
dispatch(showErrorSnackbar("Error Message 3."));
} else {
dispatch(openDialogue({
resources: data,
start: value.start,
end: value.end
}))
}
});
}
}
showErrorSnackbar是另一个action,只是调度了下面的action,它修改了store,用来显示消息:
export const showErrorSnackbar = message => {
return dispatch => {
dispatch({ type: SNACKBAR_SHOW, payload: {
message: message,
severity: "error"
}});
};
};
我的想法是我想运行一些预检查并停止请求/如果不满足则显示错误消息。然后我将请求发送到我的后端 API,并根据响应发送成功操作或显示另一条错误消息(消息 3)。
现在的问题是消息 1 和 2 在 Firefox 中不显示,但在 Safari 中按预期工作。准确地说 - 显示它们的操作已发送,但随后又立即关闭。查看dev工具栏,调用了组件的handleClose()函数。堆栈跟踪显示,它是由以下人员调用的:
handleClickAway - node_modules/@material-ui/core/esm/Snackbar/Snackbar.js:187
消息 3 显示得非常好,Safari 中的所有三个消息也是如此。
// 供参考 //
这是 Snackbar 组件:
import {useDispatch, useSelector} from "react-redux";
import Snackbar from "@material-ui/core/Snackbar";
import IconButton from "@material-ui/core/IconButton";
import {Icon} from "@material-ui/core";
import {clearSnackbar} from "../../redux/actions";
import Alert from "@material-ui/lab/Alert";
export default function SuccessSnackbar() {
const dispatch = useDispatch();
const {snackbarMessage, snackbarOpen, snackbarSeverity} = useSelector(
state => state.ui
);
function handleClose() {
dispatch(clearSnackbar());
}
return (
<Snackbar
anchorOrigin={{
vertical: "bottom",
horizontal: "left"
}}
open={snackbarOpen}
autoHideDuration={5000}
onClose={handleClose}
aria-describedby="client-snackbar"
action={[
<IconButton key="close" aria-label="close" color="inherit" onClick={handleClose}>
<Icon>close</Icon>
</IconButton>
]}
>
<Alert onClose={handleClose} severity={snackbarSeverity}>
{snackbarMessage}
</Alert>
</Snackbar>
);
}
这是减速器:
import {SNACKBAR_CLEAR, SNACKBAR_SHOW} from "../types";
const initialState = {
snackbarMessage: "",
snackbarOpen: false,
snackbarSeverity: "success"
};
const uiReducer = (state = initialState, action) => {
switch (action.type) {
case SNACKBAR_SHOW:
return {
...state,
snackbarOpen: true,
snackbarMessage: action.payload.message,
snackbarSeverity: action.payload.severity
};
case SNACKBAR_CLEAR:
return {
...state,
snackbarOpen: false
};
default:
return state;
}
};
export default uiReducer;
【问题讨论】:
-
我建议通过创建一个完整的项目来帮助其他人帮助您,该项目仅包含重现问题所需的最少部分并在此处分享。这样我们就可以在本地进行测试和调试。您甚至可以创建一个包含所有内容的 CodePen/jsFiddle/CodeSandbox,因此我们不需要在本地处理它。
-
@emi 明天会尝试这样做,感谢您的建议
标签: reactjs redux material-ui