【问题标题】:How can I conditionally redirect to a page after the axios response in react?在 axios 响应做出反应后,如何有条件地重定向到页面?
【发布时间】: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 组件检查他们是否已登录是没有意义的。甚至应该高于所有路由器的东西
  • 这也意味着当您在页面之间导航时它将位于不会重新呈现的位置,这应该可以解决问题

标签: javascript reactjs


【解决方案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 语句中执行此操作。
    猜你喜欢
    • 2019-03-20
    • 1970-01-01
    • 2021-08-15
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 2021-07-07
    • 2012-05-12
    相关资源
    最近更新 更多