在 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-routerreact-router-dom

我不会使用纯 JavaScript 在 React 应用程序中进行重定向/导航。

【讨论】:

嗨 Jason,我知道纯 javascript 是非常规的,但在这里我需要使用它,稍后我可能会更改它 好的。好吧,但是您想重定向,请在检查 API 响应后在 then 语句中执行此操作。

以上是关于在 axios 响应做出反应后,如何有条件地重定向到页面?的主要内容,如果未能解决你的问题,请参考以下文章

在 React 中提交后重定向

是否可以使用RedirectMatch有条件地重定向URL?

如何在反应中设置来自axios的响应状态

如何在上下文提供程序中使用 axios get 调用来做出反应

如何在您的登录 api 的 Json 响应后重定向用户反应本机

如何保存我最近用 axios 创建的 firebase 中的数据并做出反应?