设置状态后componentDidMount不发送数据

时间:2019-03-19 00:33:14

标签: reactjs express

我正在解码令牌以获取当前用户的电子邮件地址,并将其设置为facultyEmail状态,并将其发送至后端以获取响应。但是facultyEmail是空的,因为componentDidMount是异步的,它可以在componentDidMount()之外工作,但是我不知道有什么方法可以用componentDidMount之外的参数来处理axios get请求,我没有事件可以调用它。谢谢帮助

componentDidMount() {
  const token = localStorage.usertoken;
  const decoded = jwt_decode(token);
  this.setState({
    facultyEmail: decoded.email
  });

  axios
    .get("faculty/Course", {
      params: {
        facultyEmail: this.state.facultyEmail
      }
    })
    .then(res => {
      this.setState({
        class: res.data
      });
    })
    .catch(err => {
      console.log(err);
    });
  console.log("courses", this.state.facultyEmail);
}

3 个答案:

答案 0 :(得分:2)

setState是异步的。您必须使用setState回调或async / await

  • 使用回调
componentDidMount() {
  const token = localStorage.usertoken;
  const decoded = jwt_decode(token);
  this.setState({
    facultyEmail: decoded.email
  }, () => {
    axios
      .get("faculty/Course", {
        params: {
          facultyEmail: this.state.facultyEmail
        }
      })
      .then(res => {
        this.setState({
          class: res.data
        });
      })
      .catch(err => {
        console.log(err);
      });
    console.log("courses", this.state.facultyEmail);
  });
}
  • 使用异步/等待
async componentDidMount() {
  try {
    const token = localStorage.usertoken;
    const decoded = jwt_decode(token);
    await this.setState({
      facultyEmail: decoded.email
    });

    const res = await axios.get("faculty/Course", {
      params: {
        facultyEmail: this.state.facultyEmail
      }
    })

    this.setState({
      class: res.data
    });
    console.log("courses", this.state.facultyEmail);
  } catch (err) {
    console.log(err);
  }
}

答案 1 :(得分:0)

您使用的电子邮件与在setState中使用的同一封电子邮件进行API调用一样,不需要两个setState。这会导致我们异常,因此不建议这样做。您可以通过两种方式执行此操作:

方法1

componentDidMount() {
  const token = localStorage.usertoken;
  const decoded = jwt_decode(token);
  axios.get("faculty/Course", {
    params: {
      facultyEmail: decoded.email
    }
  }).then(res => {
    this.setState({
      class: res.data,
      facultyEmail: decoded.email
    });
  }).catch(err => {
    console.log(err);
  });
}

render() {
  console.log(this.state.class, this.state.facultyEmail);
  // This will have the values from setstate triggered inside axios.
  return(
    <div> Sample </div>
  )
}

替代方法:

loadDataFromApi(email) {
  axios.get("faculty/Course", {
    params: {
      facultyEmail: email
    }
  }).then(res => {
    this.setState({
      class: res.data
    });
  }).catch(err => {
    console.log(err);
  });
}

componentDidMount() {
  const token = localStorage.usertoken;
  const decoded = jwt_decode(token);
  this.setStats({
   facultyEmail: decoded.email
  }, () => {
     // The callback function would reflect the updated email.
     this.loadDataFromApi(this.state.facultyEmail);
  });
}

答案 2 :(得分:0)

为什么不将facultyEmail存储在内存中直到第二个setState,而避开第一个? axios调用是异步的,因此您需要将console.log放在render函数中(并且仅应在其实际处于状态时对其进行记录)。

componentDidMount() {
  const token = localStorage.usertoken;
  const decoded = jwt_decode(token);
  const facultyEmail = decoded.email;

  axios
    .get("faculty/Course", { params: { facultyEmail } })
    .then(res => { this.setState({ class: res.data, facultyEmail }); })
    .catch(err => { console.log(err); });
}

render() {
  if (this.state.facultyEmail) console.log("courses", this.state.facultyEmail);

  return ();
}