在 axios 响应做出反应后,如何有条件地重定向到页面?
Posted
技术标签:
【中文标题】在 axios 响应做出反应后,如何有条件地重定向到页面?【英文标题】:How can I conditionally redirect to a page after the axios response in react? 【发布时间】:2021-01-11 08:35:13 【问题描述】:如果 axios api 为空或状态最初为空,我如何有条件地重定向到页面。在下面的代码中,我使用 axios 更新状态,并且用户信息在状态中可用,但代码继续调用 http://userapi.com/login
in 循环。我想要实现的是,如果用户信息状态最初为空,则重定向到登录页面并进行身份验证。
class MyComponent extends React.Component
constructor()
super()
this.state =
userinfo:
componentDidMount()
axios.get('http://userapi.com/user')
.then(res =>
const userinfo = res.data;
this.setState( userinfo );
)
.catch(err =>
console.log("Fetch error", err)
)
if (Object.keys(this.state.userinfo).length === 0)
window.location = 'http://userapi.com/login';
render()
return (
<React.Fragment>
<Header>Welcome</Header>
</React.Fragment>
)
我可以很好地重定向,但问题在于连续循环。即使用户信息正在存储重定向被调用(发生在循环中)
【问题讨论】:
将你的组件包装在 withRouter Hoc 中,然后使用 props.history.push("/yourroute") 如果你使用的是 react-router 我可以很好地重定向,但问题在于连续循环。即使用户信息正在存储重定向被调用(发生在循环中) 正如@Sujit.Warrier 所说,使用push
方法,因为window.location = ...
将进行硬导航,重新加载您的应用程序并导致所有内容重新渲染。此外,最好将此检查放在组件树的更高位置。更接近根 App 组件。 Header
组件检查他们是否已登录是没有意义的。甚至应该高于所有路由器的东西
这也意味着当您在页面之间导航时它将位于不会重新呈现的位置,这应该可以解决问题
【参考方案1】:
您可以尝试以下方法:
class HeaderComponent extends React.Component
constructor()
super()
this.state =
userinfo:
componentDidMount()
axios.get('http://userapi.com/user')
.then(res =>
const userinfo = res.data;
this.setState( userinfo );
)
.catch(err =>
console.log("Fetch error", err)
)
componentDidUpdate(prevProps, userinfo )
if (userinfo !== this.state.userinfo
&& Object.keys(this.state.userinfo.w3idUser || ).length === 0)
window.location = 'http://userapi.com/login';
render()
return (
<React.Fragment>
<Header>Welcome</Header>
</React.Fragment>
)
问题在于 this.state.w3idUser
永远不存在,因为您将响应映射到 userInfo
状态。
【讨论】:
感谢这个答案,测试后肯定会在这里更新结果。【参考方案2】:Axios 返回Promise,因此下面带有if
条件的代码在更新then
块中状态的函数之前执行。因此,如果您需要在请求成功后检查更新的状态值,请将您的条件放在then
块中。
componentDidMount()
axios
.get('http://userapi.com/user')
.then((res) =>
const userinfo = res.data;
this.setState( userinfo , () =>
if (Object.keys(this.state.userinfo).length === 0)
window.location = 'http://userapi.com/login';
);
)
.catch((err) =>
console.log('Fetch error', err);
);
【讨论】:
【参考方案3】:我猜问题是 componentDidMount
,你在 axios 完成它之前重定向它是 get
请求,重构你的代码,如下所示,你可以在 axios 返回值之前显示微调器的类型:
componentDidMount()
axios.get('http://userapi.com/user')
.then(res =>
const userinfo = res.data;
this.setState( userinfo );
if (Object.keys(this.state.w3idUser).length === 0)
window.location = 'http://userapi.com/login';
)
.catch(err =>
console.log("Fetch error", err)
)
这取决于您使用的路由器,但如果您想要 javascript 方式,请检查以下代码:
// Simulate a mouse click:
window.location.href = "http://www.w3schools.com";
// Simulate an HTTP redirect:
window.location.replace("http://www.w3schools.com");
【讨论】:
我可以很好地重定向,但问题在于连续循环。即使用户信息正在存储重定向被调用(发生在循环中) 你能分享一下你的登录页面里有什么吗? 登录页面是外部 api。它返回一个带有用户信息的对象【参考方案4】:收到回复时在此处...
.then(res =>
const userinfo = res.data;
this.setState( userinfo );
)
检查 res.data 以获取用户信息。如果您确实收到了用户,那么您可以设置状态,如果没有用户重定向到登录页面。
至于重定向请查看react-router
或react-router-dom
我不会使用纯 JavaScript 在 React 应用程序中进行重定向/导航。
【讨论】:
嗨 Jason,我知道纯 javascript 是非常规的,但在这里我需要使用它,稍后我可能会更改它 好的。好吧,但是您想重定向,请在检查 API 响应后在 then 语句中执行此操作。以上是关于在 axios 响应做出反应后,如何有条件地重定向到页面?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用RedirectMatch有条件地重定向URL?
如何在上下文提供程序中使用 axios get 调用来做出反应