错误:请求失败,状态码为401:在React.js中未经授权并使用setState进行授权

时间:2019-10-13 09:48:46

标签: javascript reactjs axios

注意-以下错误仅在第一次单击应用程序的“提交”按钮时发生,并且仅在页面的第一次加载时发生。如果我再次单击“提交”按钮,则效果很好。

为了从API提取数据,我使用axios.all,为了授权JQL查询,我需要用户名和密码。在调用axios.all之前设置了授权字符串(this.setState {authString}),在每个get调用中,我都使用this.state.authString进行授权。

onSubmit = (event) => {
    event.preventDefault();
    event.stopPropagation();
    let iNumber = event.target.iNumber.value;
    let pass = event.target.password.value;
    let query = CURRENT_SPRINT_INFO;
    if (!iNumber || !pass || !query) {
      alert("Enter Valid iNumber, password and sprint info");
      return;
    }
    this.loadData(iNumber, pass, query);
  }

  loadData = (iNumber, pass, query) => {

    notify.show("Loading...", "warning", 500);
    const authString = "Basic " + btoa(iNumber + ":" + pass);
    this.setState({
      authString: authString,
      loading: true
    });

    axios.all([this.getBacklogItemsData(query), this.getBugsData(query), this.getWaveItemsData(query)])
      .then(axios.spread((backlogItems, bugs, waveTasks) => {
        notify.show("data Loaded successfully", "success", 3000);
        const { adhocIssues, scrumBoardIssues } = this.getSeparateBIItems(backlogItems.data.issues);

        this.setState({
          adhocIssues: [...adhocIssues],
          scrumBoardIssues: [...scrumBoardIssues],
          bugs: [...bugs.data.issues],
          waveBoardTasks: [...waveTasks.data.issues],
          loading: false
        })
        // set session variables
        setUserDetails(iNumber, pass);

      }))
      .catch(error => {
        notify.show(`Error occurred while fetching data`, "error", 3000);
        this.setState({ loading: false });
        throw new error(error);
      })

  }

第一次加载页面并单击我的提交按钮时,它引发错误:请求失败,状态码为401:未经授权->并且当我调试和检查时,authString为空,即authString =“”->发生这种情况在我的第一个GET调用本身上(即在this.getBacklogItemsData(query)内部)

再次单击提交按钮后,它会很好地工作

灵感来自:https://codesandbox.io/s/rm4pyq9m0o

2 个答案:

答案 0 :(得分:1)

因为this.setState是异步的。因此,您可以使用setState这样的回调:

this.setState({
      authString: authString,
      loading: true
}, () => {
   axios.all(...) // Call axios here to make sure setState done
});

更多信息,请检查文档setState here

答案 1 :(得分:1)

  

为了从API提取数据,我使用axios.all,为了授权JQL查询,我需要用户名和密码。在调用axios.all之前设置了授权字符串(this.setState {authString}),在每个get调用中,我都使用this.state.authString进行授权。

在事件处理程序中,仅当退出事件处理程序时,反应才会刷新所有状态更改。

在这里我举一个例子 https://codesandbox.io/s/runtime-firefly-v59yk

因此,在事件处理程序执行期间,当您访问this.state.authString时,它将为您提供您输入的初始值 事件处理程序。

因此,解决此问题的一种方法是使用setState的第二个参数来确保状态已更新且组件已重新呈现,就像这样

this.setState({
      authString: authString,
      loading: true
    }, () => axios.all(...));