在 React 中挣扎于 JS Promises

Struggling With JS Promises in React

我对 Java 脚本中 Promise 的概念感到困惑。我正在编写一个 React 应用程序,它使 GET 调用 Java 中的单独 API 服务,我想将其状态存储在 useState() 挂钩中。所以这是我的 fetch 代码:

const ratingsUrl = "%URL%";
const base64 = require("base-64");
const login = "login";
const password = "password";

function fetchRatings() {
  return fetch(ratingsUrl, {
    method: "GET",
    headers: new Headers({
      Authorization: "Basic " + base64.encode(login + ":" + password),
    }),
  })
    .then((response) => response.json())
    .catch(handleError);
}

现在我正尝试将其状态存储在我的页面组件的一个钩子中:

function DisplayPage(){
  const [ratings, setRatings] = useState(fetchRatings());

.
.
.
}

现在,数据 returns 但它在 Promise 中,因此导致错误:

Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Array(20)

我需要做的是在一个钩子中初始化数据,然后 return 在 Table 中初始化它,这样我就可以通过它进行映射。但是,每当我尝试做类似

的事情时
ratings.map()

我在控制台中收到 TypeError 提示 ratings.Map is not a function

我知道 fetch 库 return 的数据是异步的,但我真正想要的是将 PromiseResult 存储在 useState() 挂钩中这样我就可以进一步对其进行操作。

async 方法 return 承诺。如果您直接在 setRatings 状态变量中设置承诺的结果,您将获得承诺。

通常这会被重写成这样:

function DisplayPage(){
  const [ratings, setRatings] = useState(null);

  useEffect(() => {

    fetchRatings
      .then(result => setRatings(result))
      .catch(err => console.error(err));

  }, []);
 
  if (ratings === null) return <div>loading...</div>;
  
  /* .. do your thing .. */

}

这个怎么样,

const [ratings, setRatings] =  useState();
useEffect(()=>{
         fetch(ratingsUrl, {
method: "GET",
headers: new Headers({
  Authorization: "Basic " + base64.encode(login + ":" + password),
})}).then((response) => {let res = response.json();
    setRatings(res)
      })
.catch(handleError);
 },[])

我建议使用 useEffect 钩子来设置初始状态。(类似于 componentDidMount)

因此,如果您期望的响应是一个数组。

const [ratings, setRatings] = useState([]);

然后在 useEffect 挂钩中,当您从获取请求中获得响应时更新状态。 这样,如果您在请求完成之前在 DOM 中的某处映射评分,就可以防止错误。

useEffect(){
    fetch(ratingsUrl, {
        method: "GET",
        headers: new Headers({
            Authorization: "Basic " + base64.encode(login + ":" + password),
        }),
    })
    .then((response) => {
         response.json()
    })
    .then(res => setRatings(res))
    .catch(handleError);

因为提取是异步运行的,所以您将无法使用调用 fetchRatings 的直接结果来初始化您的状态。

幸运的是,有几个相当简单的方法可以处理这个问题。您可以使用空值初始化您的状态,然后在 fetchResults 解析后更新它:

function DisplayPage() {
  // initially ratings will be undefined
  const [ratings, setRatings] = useState();

  // update state when fetchResults comes back
  fetchResults().then(response => setRatings(response));

  // ...

为了提高可读性,上面的例子省略了这个,但你通常会通过 useEffect 这样做,所以它会在你的组件安装或相关输入(通常是道具,称为效果依赖项)时运行) 变化:

function DisplayPage() {
  const [ratings, setRatings] = useState();

  useEffect(() => {
    fetchResults().then(response => setRatings(response));
  }, []) // empty dependencies array will cause the effect to run only once, on mount

  // ...