首页 > 解决方案 > JavaScript 使用 async/await 确保我在实现之前检索值,但仍然返回“未定义”

问题描述

代码

async function getStudents() {
  var reqObj = new RequestHandler("/students/all/");
  let { students } = await reqObj.sendRequest();
  console.log(students, students.length);
  return students;
}

export default function Students(props) {
  var students = getStudents();
  return (
    <main className="content-section">
      <h1>Students</h1>
      <span className="help-text">
        You have {`${students.length}`} students.
      </span>
    </main>
  );
}

...

export class RequestHandler {
  // Base class for handling requests
  constructor(url, method = "GET", contentType = "application/json") {
    this.url = url;
    this.method = method;
    this.contentType = contentType;
    this.request_conf = {
      method: this.method,
      url: this.url,
      headers: {
        "Content-Type": this.contentType,
        "X-CSRFToken": cookies.get("csrftoken"),
      },
      credentials: "same-origin",
    };
  }
  async sendRequest() {
    const response = await axios(this.request_conf);
    var data = isResponseOK(response);
    return data;
  }
}

函数内console.log(students, students.length);getStudents()输出正如我所期望的那样:[] 0,但尽管试图使其成为一个异步函数,但Students组件仍然undefined作为值返回。Students在组件中读取相同值的最简单方法是什么?

免责声明

我是 JavaScript 的初学者,尤其是 Promises,所以如果我在这里遗漏了一些非常简单和/或明显的东西,请告诉我,不要对它有毒 :)

标签: javascriptreactjsasync-await

解决方案


React 的“渲染”函数是一个同步的、纯函数。它不能等待值被呈现。这就是生命周期方法和状态的用途。

使用useState钩子将students数组保持在状态,并使用useEffect具有空依赖数组的钩子来调用getStudents并等待 Promise 解决并将状态更新入队并触发重新渲染。

export default function Students(props) {
  // state to hold values
  const [students, setStudents] = React.state([]);

  // effect to fetch values
  React.useEffect(() => {
    getStudents().then(students => setStudents(students));
  }, []); // <-- empty dependency == run once on component mount

  return (
    <main className="content-section">
      <h1>Students</h1>
      <span className="help-text">
        You have {`${students.length}`} students.
      </span>
    </main>
  );
}

文档

如果你更喜欢async/awaitPromise 链:

React.useEffect(() => {
  const fetchStudents = async () => {
    try {
      const students = await getStudents();
      setStudents(students);
    } catch(error) {
      // handle error, log it, etc...
    }
  };
  fetchStudents();
}, []);

推荐阅读