无法在我的React应用中获取API,未处理的拒绝(TypeError)

时间:2020-08-21 03:00:31

标签: reactjs

我试图通过我的reactapplication调用内部烧瓶API函数,

export default function ThermoBreastCancerIntroPage({ ...rest }) {
  const [is_logged_in, set_is_logged_in] = useState('false');
  React.useEffect(() => {
    window.scrollTo(0, 0);
    document.body.scrollTop = 0;
    fetch('http://127.0.0.1:9000/api/is_logged_in/').then(results => results.json())
      .then(data => {
        const {name} = data.results[0];
        set_is_logged_in(name.res);
        console.log(is_logged_in);
      });
  }, []);

flask API返回如下响应:

return jsonify({'res':False})

但是我在浏览器中遇到以下错误:

Unhandled Rejection (TypeError): Cannot read property '0' of undefined
(anonymous function)
C:/ThermoAnalyser/material-kit-pro-react-v1.9.0/src/views/LandingPage/ThermoBreastCancerPage.js:37
  34 | window.scrollTo(0, 0);
  35 | document.body.scrollTop = 0;
  36 | fetch('http://127.0.0.1:9000/api/is_logged_in/').then(results => results.json())
> 37 |   .then(data => {
     | ^  38 |     const {name} = data.results[0];
  39 |     set_is_logged_in(name.res);
  40 |     console.log(is_logged_in);

我不确定我在哪里做错了吗?

1 个答案:

答案 0 :(得分:0)

问题

您的诺言链中的某些情况是返回诺言拒绝或引发错误,应捕获并处理这两种情况。

fetch

  • 针对任何网络错误和已取消的请求返回拒绝的承诺
  • 返回所有其他请求的已解决承诺,因此您需要先检查ok状态

results.json

  • 如果成功解析JSON响应,则返回已解决的诺言
  • 可以拒绝任何处理错误

您的处理逻辑

  • 如果data.results不是不是数组,或者是长度为0的数组,则尝试访问undefined属性也会引发错误

建议

  1. 检查是否成功获取请求
  2. 在承诺链中添加catch

代码

fetch('http://127.0.0.1:9000/api/is_logged_in/')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => {
    const {name} = data.results[0]; // <-- if this throws, is ok since now caught
    set_is_logged_in(name.res);
  })
  .catch(error => {
    console.error(error);
    // any other error handling and accounting the app/component needs
  });

第二个小问题

set_is_logged_in(name.res);
console.log(is_logged_in);

排队的反应状态更新是异步的,并且在渲染周期之间进行处理,因此尝试在入队后立即记录“已更新”状态将仅记录来自当前的状态渲染周期,而不是您期望的 next 状态。当状态值更新时,您应该使用效果进行记录。

useEffect(() => {
  console.log(is_logged_in);
}, [is_logged_in]);