【问题标题】:React fetch data before render class component在渲染类组件之前反应获取数据
【发布时间】:2021-07-12 19:01:24
【问题描述】:

我已经尝试了我能找到的所有选项,但我不明白我做错了什么。 我的 axios 获取数据更新,但是当我使用条件时,它总是呈现第一个状态数据。这是我的代码。

    import axios from 'axios';
import React, { Component,  } from 'react'
import { Redirect } from 'react-router-dom';
import { Route } from 'react-router-dom';

class ProtectedRoute extends Component{
  // _isMounted = false;
  constructor(props) {
    super(props);
    this.state = {
        Authenticated: undefined
    };
  }

  componentWillMount(){
    // this._isMounted = true;
        axios.get('/api/get_me')
        .then(res => {
          if (this._isMounted) {
            if (res.data.logged_in == true) {
              this.setState({Authenticated: true});
              console.log(this.state.Authenticated)
            }
          }
        })
        .catch(err =>{
          this.setState({Authenticated: false});
        });
    }
    // componentWillUnmount() {
    //   this._isMounted = false;
    // }
    render(){
        const { component: Component, ...props } = this.props;
        const Authenticated = this.state;
        console.log(Authenticated)
        if (Authenticated == true) {
          return(<Route {...props} render={props => (<Component {...props} />)}/>)
        }
        else{
          return(<Redirect to='/login' />)
        }
        // return (
        //   <Route 
        //     {...props} 
        //     render={props => (
        //       Authenticated ?
        //         <Component {...props} /> :
        //         <Redirect to='/login' />
        //     )} 
        //   />
        // )
    }
}

export default ProtectedRoute;

每当我使用条件时,它都会带有 undefined 值。我想使用类组件而不是功能挂钩。我不明白我做错了什么以及我能做些什么来解决这个问题?我已经尝试了所有评论部分的代码,但没有解决。 这是错误。

【问题讨论】:

  • if (this._isMounted) - 你在哪里将标志设置为true?它看起来到处都被注释掉了
  • 你有两个带有Authenticated的控制台日志,你怎么知道哪个是错误输出?
  • @NadiaCibrikova 它总是呈现第一个状态,正如您在控制台中看到的那样,它显示为未定义。

标签: reactjs react-redux react-router axios react-hooks


【解决方案1】:

您缺少 name 属性。由于它是一个对象,所以你必须这样称呼它。否则它将返回 undefined。

const Authenticated = this.state.Authenticated

【讨论】:

  • 显示未定义
【解决方案2】:

这是不正确的解构

const Authenticated = this.state;

正确一个

const { Authenticated } = this.state;

或 像这样分配

const Authenticated = this.state.Authenticated ;

查看此内容以更好地了解Destructuring

【讨论】:

    【解决方案3】:

    您必须在第 7 行取消注释 // this._isMounted = true; 的 componentWillMount 和 _isMounted = false。

    您在Authenticated 状态下获得未定义状态,因为您的 API 可能正在解析,但 this._isMounted 未定义,因为您已将它们注释掉。

    如其他答案所述,您还需要通过适当的解构来正确地获得您的 Authenticated 状态。 const { Authenticated } = this.state;

    因此,关于您在等待 API 响应时不想重定向的响应。您可能想要添加加载状态。这样,您的应用会在等待您的 API 解析而不是重定向时显示一些内容。

    constructor(props) {
      super(props);
      this.state = {
        Authenticated: undefined
        isLoading: true,
      };
    }
    
    componentWillMount(){
      this._isMounted = true;
      axios.get('/api/get_me')
        .then(res => {
          if (this._isMounted) {
            if (res.data.logged_in == true) {
              this.setState({Authenticated: true});
              console.log(this.state.Authenticated)
            }
          }
         })
         .catch(err =>{
           this.setState({Authenticated: false});
         })
         .finally(() => {
           this.setState({ isLoading: false });
         });
    }
    
    render(){
        const { component: Component, ...props } = this.props;
        const {Authenticated, isLoading} = this.state;
        console.log(Authenticated)
    
        if(isLoading) {
          return <div>Loading...</div>
        }
        if (Authenticated == true) {
          return(<Route {...props} render={props => (<Component {...props} />)}/>)
        }
        else{
          return(<Redirect to='/login' />)
        }
        // return (
        //   <Route 
        //     {...props} 
        //     render={props => (
        //       Authenticated ?
        //         <Component {...props} /> :
        //         <Redirect to='/login' />
        //     )} 
        //   />
        // )
    }
          
    

    【讨论】:

    • 我已将这些代码与评论分享,以便所有人都能理解我使用过它们但没有解决我的问题。让我再次告诉您,我正确获取了所有数据,但是当我使用 if auth== true 之类的条件时,可以去任何地方。但是当我渲染它时,它的第一个状态是未定义的,然后在渲染后它就实现了。但我的情况已经呈现。
    • 啊,你的意思是当你导航到 ProtectedRoutes 时,它最初是未定义的?然后在您的 fetch 解决后变为 true,对吗?
    • 是的,但它会重定向到登录页面我想花一些时间来呈现或重定向
    • 好的,这里有一个解决方法。您可以在等待响应时向您的状态添加加载状态。您创建了一个在等待 axios.get('/api/get_me') 时显示的加载组件
    • 我已经为我的意思添加了更多上下文。让我知道它是否有帮助! @CoderBoy
    【解决方案4】:

    在 finally 块中设置状态后,您是否检查过您的状态是什么样的?您确定没有覆盖其他值吗?

    尝试使用扩展运算符保留状态中的每个值: React - Overwrite part of the state.object's values whilst preserving the old ones.

    另外,我认为 componentWillMount 真的不推荐了,这里是官方指导更安全的版本来替换它:

    https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html

    【讨论】:

      猜你喜欢
      • 2022-01-24
      • 2018-02-19
      • 2019-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-01
      相关资源
      最近更新 更多