嘿,我正在尝试为 React-router 制作小型应用程序,我正在尝试发送 API 请求(我没有后端,这就是我使用 promise 的原因)当我单击“链接”时,它正在重定向,而不是等待我的异步/等待,你能告诉我吗?我做错了什么? 首先想到我可以用 Prop 传递历史,然后
history.push("/someURL");
但我的第二个想法是,如果我可以用
总而言之,我需要等到我的请求( promise )结束后我需要更改网址
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import { toast } from 'react-toastify';
const StyledButton = styled.button`
width: 100%;
border-radius: 10px;
background-color: #24b571;
color: #ffffff;
font-weight: bold;
margin-bottom: 5px;
`;
const SaveButton = ({
children,
saveValidation,
message,
to,
setIsLoading,
}) => {
const promiseFunc = () =>
new Promise((resolve) => {
setTimeout(() => {
resolve(5);
}, 5000);
});
const onClickHandler = async (event) => {
setIsLoading(true);
const control = saveValidation(); // returns true or false
if (!control) {
toast.error(message);
event.preventDefault();
} else {
try {
const a = await promiseFunc();
alert(a);
} catch {
alert('error');
}
console.log(control);
}
setIsLoading(false);
};
return (
<Link to={to}>
<StyledButton onClick={onClickHandler}>{children}</StyledButton>
</Link>
);
};
export default SaveButton;
SaveButton.propTypes = {
children: PropTypes.node.isRequired,
saveValidation: PropTypes.func.isRequired,
to: PropTypes.string.isRequired,
message: PropTypes.string,
setIsLoading: PropTypes.func,
};
SaveButton.defaultProps = {
message: 'Fill all values',
setIsLoading: () => {},
};
最佳答案
问题
这里的主要问题是您正在渲染用户可以与之交互的两个组件/元素,这通常被认为是 UI/UX 中的反模式。单击按钮并调用其 onClick
处理程序,并且单击事件冒泡,Link
通过导航来处理它。这些事件是彼此分开处理的。您可以在按钮的点击处理程序中停止onClick
事件传播,但随后Link
将停止工作。
解决方案
我建议单独使用样式按钮,并在异步逻辑问题结束时使用命令式导航,而不是 Link
提供的声明式导航。使用 react-router-dom
中的 useHistory
Hook (如果使用 RRDv6,则使用 useNavigate
)。
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { useHistory } from 'react-router-dom'; // <-- import hook
import { toast } from 'react-toastify';
const StyledButton = styled.button`
...
`;
const SaveButton = ({
children,
saveValidation,
message,
setIsLoading,
to,
}) => {
const history = useHistory(); // <-- use hook
const promiseFunc = () => new Promise((resolve) => {
...
});
const onClickHandler = async (event) => {
setIsLoading(true);
const control = saveValidation();
if (!control) {
toast.error(message);
event.preventDefault();
} else {
try {
const a = await promiseFunc();
alert(a);
} catch {
alert('error');
}
console.log(control);
}
setIsLoading(false);
history.push(to); // <-- imperative navigation
};
return (
<StyledButton onClick={onClickHandler}>{children}</StyledButton>
);
};
关于javascript - React Link async/await 不等待代码块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70237476/