【问题标题】:React is not rendering if state is set in constructor by a function如果函数在构造函数中设置状态,则 React 不会呈现
【发布时间】:2021-07-05 01:44:41
【问题描述】:

我正在尝试根据用户登录状态启动页面。为此,我尝试通过一个函数设置初始状态,但在 api 调用完成后它没有更新视图。 目前我在执行代码时看到了第 3 部分。

    import React, { Component } from 'react';
    import axios from 'axios';
    import { API_BASE_URL } from './constants/apiConstants';

    export default class App extends Component {
    constructor(props) {
        super(props)

        this.state = {
            loginStatus: this.loginUpdate(),
        }
    }

    loginUpdate(){
        let token = localStorage.getItem("TOKEN");

        let tmpStatus = token!==""?true:false;

        if(tmpStatus){
            const payload = {
                "token": token
            }
    
            axios.post(API_BASE_URL + 'loginCheck', payload)
                .then((response) => {
                    tmpStatus=response.data.response;
                    return tmpStatus;
                });
        }else{
            return tmpStatus;
        }

        return null;
      }

    render() {
        return (
            <>
                {this.state.loginStatus===true &&
                    <p>Part 1</p>
                }

                {this.state.loginStatus===false &&
                    <p>Part 2</p>
                }

                {this.state.loginStatus===null &&
                    <p>Part 3</p>
                }
                </>
        )
    }
}

【问题讨论】:

    标签: reactjs function constructor state render


    【解决方案1】:

    问题:

    您应该更新 Axios 的 then callback 内的状态变量。您在 loginUpdate function 中有一个 API 调用,但问题是您的 HTML 先呈现,然后您的 API 响应出现。此外,您在Axios 之前错过了return 声明,但这样做也不会解决您的问题。

    解决方案:

    您应该在then callback 中设置您的状态变量。

    import React, { Component } from 'react';
    import axios from 'axios';
    import { API_BASE_URL } from './constants/apiConstants';
    
    export default class App extends Component {
    constructor(props) {
        super(props)
    
        this.state = {
            loginStatus: localStorage.getItem("TOKEN") !== '' ? true : false,
        }
    }
    
    componentDidMount() {
        this.loginUpdate();
    }
    
    loginUpdate(){
        let token = localStorage.getItem("TOKEN");
    
        let tmpStatus = token!==""?true:false;
    
        if(tmpStatus){
            const payload = {
                "token": token
            }
    
            axios.post(API_BASE_URL + 'loginCheck', payload)
                .then((response) => {
                    this.setState({ loginStatus: response.data.response });
             });
        }else{
            return tmpStatus;
        }
    
        return null;
      }
    

    【讨论】:

    • 确实返回始终为真是一个错误......我也按照您的建议更新了答案。感谢您的回复。
    【解决方案2】:

    你也应该返回 axios 结果。

        return axios.post(API_BASE_URL + 'loginCheck', payload)
                .then((response) => {
                    tmpStatus=response.data.response;
                    return tmpStatus;
                });
    

    【讨论】:

    • 你仍然错过了 return 的 axios。不仅在 then(...) 内部,还应该返回整个 axios。
    【解决方案3】:

    我能够通过以下方法解决问题:

    import React, { Component } from 'react';
    import axios from 'axios';
    import { API_BASE_URL } from './constants/apiConstants';
    export default class App extends Component {
    constructor(props) {
        super(props)
    
        this.state = {
            loginStatus: null,
        }
    }
    
    componentDidMount() {
        this.loginUpdate();
    }
    
    loginUpdate(){
        let token = localStorage.getItem("TOKEN");
    
        let tmpStatus = token!==""?true:false;
    
        if(tmpStatus){
            const payload = {
                "token": token
            }
    
            axios.post(API_BASE_URL + 'giris/kontrol', payload)
                .then((response) => {
                    tmpStatus=response.data.response;
                    this.setState({loginStatus:tmpStatus});
                });
        }else{
            this.setState({loginStatus:tmpStatus});
        }
      }
    
    render() {
        return (
            <>
                {this.state.loginStatus===true &&
                    <p>Part 1</p>
                }
    
                {this.state.loginStatus===false &&
                    <p>Part 2</p>
                }
    
                {this.state.loginStatus===null &&
                    <p>Part 3</p>
                }
                </>
        )
      }
    }
    

    【讨论】:

    • 嘿,为什么在this.setState({loginStatus:true}); 中总是将 loginStatus 设置为 true,如果在 componentDidMount 中调用 loginUpdate 函数会更好。你可以看看我的回答。
    • 更新了 this.setState({loginStatus:tmpStatus});并添加了 componentDidMount 函数......谢谢。
    【解决方案4】:

    在构造函数运行时,“loginStatus”状态设置为方法“loginUpdate()”的第一个结果,即“null”。当在构造函数中调用“loginUpdate()”方法时,它会启动 axios,但不等待 axios 的响应。它将以异步方式运行。设置“null”值后,构造函数完成其工作。所以, axios 的结果永远不会被使用。

    因此,您应该在获取 axios 结果时使用 this.setState() 函数。此外,您不应在构造函数中使用该方法。因此,如果将方法放在“componentDidMount”中,并在 axios 上获取结果后使用 setState 函数,就会得到预期的结果。在 setState 函数中,您应该使用 axios 响应设置“loginStatus”。

    【讨论】:

      猜你喜欢
      • 2019-04-04
      • 2019-04-15
      • 1970-01-01
      • 2019-09-04
      • 2019-02-22
      • 2018-06-09
      • 1970-01-01
      • 2020-03-03
      • 2022-07-07
      相关资源
      最近更新 更多