【问题标题】:React map rendering element in random order以随机顺序反应地图渲染元素
【发布时间】:2021-10-27 23:29:18
【问题描述】:

我做了一个 pokedex 网站,只是为了搞砸,我尝试将 12 个 pokemon 渲染到一个页面,直到用户单击下一页,然后它将根据 pokeapi 渲染下一个 12 个基础:“https://pokeapi. co/api/v2/pokemon?offset=0&limit=12"

  function getAllPokemon(url) {
    fetch(url)
      .then((res) => res.json())
      .then((data) => {

        let allPromise = Promise.all(
          data.results.map((e) => {
            return new Promise((resolve, reject) => {
              resolve(e);
            });
          })
        );
        allPromise.then((e) => {
          e.map((res) => {
            fetch(res.url)
              .then((e) => e.json())
              .then((e) => {
                setListPokemon((listPokemon) => [
                  ...listPokemon,
                  {
                    id: e.id,
                    name: res.name,
                    url: res.url,
                    image_url:
                      e.sprites.other["official-artwork"].front_default,
                  },
                ]);
              });
          });
        });
      });
    setLoading(false);
  }

然后我会使用地图将所有数据呈现到屏幕上。

{listPokemon.map((p) => (
              <Grid>
                  <Card>
                    <CardMedia
                      component="img"
                      image={p.image_url}
                      alt={p.name}
                    />
                    <CardContent>
                      {p.id}.{setCap(p.name)}
                    </CardContent>
                  </Card>
              </Grid>
            ))}

我遇到的问题是有时 map 会以随机顺序渲染元素,大多数时候它仍然是升序。

据我所知,当我尝试在手机(比我的 PC 慢)上运行应用程序时,这种情况发生得更频繁。

这是因为滞后吗?

有没有办法确保我按照添加的顺序渲染元素?

【问题讨论】:

    标签: javascript reactjs api


    【解决方案1】:

    请注意,您正在 for 循环内发出异步请求。在这种情况下,您应该做出一系列承诺并使用Promise.all()。结果将按特定顺序排列,如 here 所述,因此您只能使用排序的数据集合更新您的状态一次,然后呈现您的列表。

    【讨论】:

    • 另外你不应该把setLoading(false)放在那里,它应该在最后一个请求完成并且状态已经更新之后完成。
    • 那么我是在 fetch 中使用 promise.all 还是在 fetch 中使用 promise.all?我对 promises 没有太多经验。
    • 所以我建议你阅读一些articles 和documentation。基本上,您需要创建一组由fetch 返回的承诺(您可以使用data.results 上的map 函数来生成一个),然后将其传递给Promise.all() 函数,最后将结果提取到'. then()`,但这一次它将是一个连续请求的结果数组。
    • 所以我更新了我的代码(看上面)和 idk,如果我做得对的话,但它仍然不起作用。
    • 请不要更改问题中的代码,因为问题没有意义。你弄错了,正如我所说,你必须使用data.results 数组,使用.map() 生成由fetch() 返回的promises 数组(不要对它们执行.then() 方法!)和然后将其传递给Promise.all() 函数。它将返回一个全新的Promise,您需要使用.then() 处理它。仔细阅读并查看文档中的示例和我上面链接的文章。这是一个很难的话题,你需要慢慢来。
    猜你喜欢
    • 2020-08-20
    • 2017-10-21
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多