为什么我会得到一个TypeError:this.getToken不是一个函数 - React JS

时间:2018-05-17 21:49:53

标签: javascript json reactjs api

我创建了一个使用json API的登录页面。登录页面在成功验证后生成令牌,并将用户定向到包含三个下拉框的页面。只关注其中一个下拉框,我试图让下拉框根据其令牌显示客户端的用户名。

登录页面从另一个对用户进行身份验证的反应JS页面调用一个函数。

功能:

getToken() {
        // Retrieves the user token from localStorage
        return localStorage.getItem('id_token')
    }

在我的目标网页中,其中包含下拉框,我有以下代码:

   componentDidMount() {
        fetch('http://theClientAPI:1111/api/clients', {
            method: 'GET',
            headers: {
                'Content-type': 'application/json',
                'Authorization': `Bearer ${this.getToken()}`
            },
        })
        .then(results => results.json())
        .then(data => this.setState({ data: data }))
    }

在render()部分,我有以下内容:

 <div>
        <select className="custom-select" id="clientName">
                { this.state.data.map(item =>(
                <option key={item.clientName}>{item.clientName}</option>
                ))
                }
            </select>
        </div>

错误出现在我的Fetch的这一行:

'Authorization': `Bearer ${this.getToken()}`

我可以得到一些关于我做错的帮助吗?如果您需要更多信息,请与我们联系。我在我的登录信息和以下身份验证页面后面发布了代码:

登录页面:https://codepen.io/lkennedy009/pen/GdYOYe?editors=0010#0 AuthService页面:https://codepen.io/lkennedy009/pen/xjyPMY

1 个答案:

答案 0 :(得分:1)

您的代码可能存在一些错误。

  1. 通常的做法是在构造函数中绑定您的函数,并为您节省可能遇到的任何其他错误

    constructor(props) {
        super(props);
    
        // This binding is necessary to make `this` work in the callback
        this.getToken = this.getToken.bind(this);
    }
    
  2. 而不是像这样调用你的函数

    'Authorization': `Bearer ${this.getToken()}`
    

    总是尝试在常量中定义它,它可以帮助调试,这是一个很好的做法,因为函数可以变得复杂,并且使更小的组件/模式成为使React有用的原因 - 所以你应该这样做。所以不要上面的例子尝试这样的事情:

    const bearerToken = this.getToken();
    //check if you even get what you expect
    console.log(bearerToken);
    ...
    'Authorization': `Bearer ${bearerToken}`
    
  3. 最后,这些是我尝试让您的代码工作的更改:

    constructor(props) {
        super(props);
    
        this.getToken = this.getToken.bind(this);
    }
    
    componentDidMount() {
        const bearerToken = this.getToken();
    
        fetch('http://theClientAPI:1111/api/clients', {
            method: 'GET',
            headers: {
                'Content-type': 'application/json',
                'Authorization': `Bearer ${bearerToken}`
            },
        })
        .then(results => results.json())
        .then(data => this.setState({ data: data }))
    }
    
    getToken() {
        return localStorage.getItem('id_token'); 
    }
    
  4. 我在componentDidMount之后定义getToken的原因是因为AirBnB的Jll的ESlint规则如果在componentDidMount或其他保留的React函数(生命周期和其他)上定义了它将引发警告

相关问题