【问题标题】:useState Hook - How can I append an item to the end of a stateful array? [closed]useState Hook - 如何将项目附加到有状态数组的末尾? [关闭]
【发布时间】:2021-10-01 13:48:45
【问题描述】:

我正在尝试使用 useState Hook 填充数组。这个项目是用 Next.js 和 Tailwind 制作的。

在 map 函数的每次迭代中,我想在数组末尾添加一个项目,直到没有剩余项目为止。

我的目标是拥有一个充满项目的有状态数组,以便我可以操作所有项目。

谢谢。

index.js

import { useState } from "react";
import Head from "next/head";
import Image from "next/image";
import requests from "../components/requests";
import Content from "../components/Content";
import Header from "../components/Header";

export const getStaticProps = async () => {
  const res = await fetch("https://pokeapi.co/api/v2/pokemon?limit=2000/");
  const pokemonData = await res.json();

  return {
    props: { pokemon: pokemonData },
  };
};

export default function Home({ pokemon }) {
  return (
    <>
      <Header />
      <main className="flex flex-col items-center justify-center sm:flex-row sm:flex-wrap">
        {pokemon.results.map((pokemon) => (
          <Content key={pokemon.name} pokemon={pokemon} />
        ))}
      </main>
    </>
  );
}

内容.js

import React, { useState, useEffect } from "react";
import Image from "next/image";

const Content = ({ pokemon }) => {
  const [Pokemon, setPokemon] = useState({ name: [] });
  // name.forEach((name) => name[0].toUpperCase() + name.substring(1));

  const url = pokemon.url;
  const pokemonIndex = url.split("/")[url.split("/").length - 2];
  const imageUrl = `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${pokemonIndex}.png`;

  useEffect(() => {
    setPokemon((prevState) => ({
      ...prevState,
      name: prevState.name.concat(pokemon.name),
    }));
  }, [pokemon]);

  console.log(Pokemon);

  return (
    <div className="p-5">
      <h1 className="text-center text-3xl font-bold">{pokemon.name}</h1>
      {/* <Image src={Pokemon.imageUrl} width="250" height="250" /> */}
    </div>
  );
};

export default Content;

【问题讨论】:

  • 您的问题最初并不清楚,看起来好像您只是在concat 通话中错过了[]。但现在看来您正在尝试创建一个包含所有已渲染口袋妖怪的状态,该状态应该由您的所有 Content 组件共享。首先,您是否真的需要从每个 Content 修改 Pokemons 如果没有,那么您可以简单地将其作为道具传递。其次,您确定不能使用传递给Content 或类似方式的一些额外道具从父级处理。第三,如果两者都不是,请参考this answer

标签: javascript reactjs react-hooks next.js use-state


【解决方案1】:

我假设,您希望在 Content 组件中包含完整的 口袋妖怪 (pokemon.results) 列表。一种更简单的方法是将单独的 prop pokemons={pokemons.results} 传递给 Content 组件。

【讨论】:

  • 这有点工作。但是,在每次 map() 迭代中,状态会再次更新为相同的 pokemons.results 数组。这样可以吗?您如何看待在组件内部映射项目而不是映射组件本身?
  • 所以即使你想在每次渲染时更新列表,状态也会更新。对于每张地图,正在创建一个新的单独组件。所以我认为为每个地图组件传递整个口袋妖怪列表不会有任何害处。完全不会影响性能,imo。我也同意你的观点,你可以映射组件内的所有口袋妖怪。这是非常好的和正确的方式。
【解决方案2】:

您可以创建一个新数组并将旧数组的内容与最后添加的新元素展开。

useEffect(() => {
    setPokemon((prevState) => ({
      ...prevState,
      name: [
        ...preveState.name,
        pokemon.name
      ]
    }));
  }, [pokemon]);

【讨论】:

  • 我已经尝试过了,但每次迭代都会给我一个新数组,其中包含一个项目(仅限当前口袋妖怪名称)。在它开始创建新数组之前,我还会得到很多空数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-19
  • 2023-03-07
  • 1970-01-01
  • 2017-07-10
相关资源
最近更新 更多