【问题标题】:React pushing to array duplicates it instead of adding反应推送到数组复制它而不是添加
【发布时间】:2022-11-18 06:29:22
【问题描述】:

有人可以帮我解决这个问题吗?我有一个名为“filteredPokemon”的状态,它根据一些东西获取一个 pokemon 列表,然后我将它传递给这个名为 PokemonDisplayArea 的函数,在那里我继续显示 pokemon 列表。但是,当我更改偏移量时,我希望将行为添加到“卡片”的先前状态,这是呈现 HTML 的元素,但是相反,它会获取最新的 filteredpokemon 并将其附加两次。任何帮助,将不胜感激!

这是一个视频 https://clipchamp.com/watch/EcMJbOMjOaL

编码:

function PokemonDisplayArea({pokemons}) {

const [filteredPokemon, setFilteredPokemon] = useState([]);
const [offset, setOffset] = useState(20);
const [cards, setCards] = useState([]);




useEffect(() => {
  let cardsSkele = [];

  if (filteredPokemon.length > 0) {
    for (let i = 0; i < filteredPokemon.length; i++) {
      if (undefined !== filteredPokemon[i].name) {

        cardsSkele.push(<PokemonCard key={filteredPokemon[i].id} name={filteredPokemon[i].name}></PokemonCard>);
        cardsSkele.sort((a, b) => a.key - b.key)
      }
    }
    setCards(prevArray => [...prevArray, ...cardsSkele]);


  }


}, [filteredPokemon])




  // SEARCH POKEMON RESULTS

  // FILTER POKEMON RESULTS




  return (
    <div className="pokemon__display-area">
      <GetFilteredPokemon pokemons={pokemons} amount={20} offset={offset} filteredPokemon={filteredPokemon} setFilteredPokemon={setFilteredPokemon}></GetFilteredPokemon>
      {cards}
    </div>
  )
}

任何帮助将不胜感激,我是初学者,谢谢!

我尝试将不同的状态传递给 useEffect,并尝试在控制台记录数据,但数据似乎变化良好,列表只是重复。

【问题讨论】:

  • 无需在 useEffect 中创建新的现有卡片数组,您需要首先检查过滤的口袋妖怪中的项目是否是现有卡片的一部分,然后合并数据并合并,这将消除重复
  • 这个useEffect的目的是为filteredPokemon中的项目设置cards吗?还是对之前的item设置cards并过滤合并?
  • @JohnLi 它应该从 filteredPokemon 中获取更改后的更新数据,并将新数据附加到之前已经存在的数据中。

标签: javascript reactjs ecmascript-6


【解决方案1】:

对于初学者,我只是将数据存储在状态中而不是组件本身,因为它很容易推理和转换。

迭代卡片并更新现有项目的数据或添加新项目。沿着这些路线的东西。

function getUpdatedCardsData(prevCards, filteredPokemon) {
  // get list of all the ids for the filtered pokemons
  const filteredPokemonIds = filteredPokemon.map(fp => fp.id);

  // This will combine the data for existing cards that are part of 
  // filteredPokemon and maintain a map of ids that are new and need to be added to cards
  const updatedCards = prevCards.reduce((memo, card) => {
    const cardId = card.id;

    const isNewCard =  !filteredPokemonIds.includes(cardId);

    // add it to the map if new
    if(isNewCard) {
      memo.newCardIds.push(cardId);
    } else {
      // find the card that is in filtered pokemon
      const found = filteredPokemon.find(fp => fp.id === cardId);

      if(found) {
        const updatedCard = {
          ...card,
          ...found
        };

        memo.updatedCards.push(updatedCard);
      }
    }

    return memo;
  }, {
    updatedCards: [],
    newCardIds: []
  });
}

function getNewCards(newCardIds, filteredPokemon) {
 // List of the new cards 
  const newCards = newCardIds.reduce((memo, newCardId) => {
    const found = filteredPokemon.find(fp => fp.id === newCardId);

    if(found) {
      memo.push(found);
    }

    return memo;
  }, []);
}

function PokemonDisplayArea({pokemons}) {

const [filteredPokemon, setFilteredPokemon] = useState([]);
const [offset, setOffset] = useState(20);
const [cards, setCards] = useState([]);


useEffect(() => {
    if(filteredPokemon) {
    setCards(prevCards => {
        const {
        updatedCards,
        newCardIds
      } = getUpdatedCardsData(prevCards, filteredPokemon);
      
      const newCards = getNewCards(newCardIds, filteredPokemon);
      
      // add updated and new and sort them
      const sortedCards = [...updatedCards, ...newCards].sort((a, b) => a.id - b.id);
      
      return sortedCards;
    });
  }
}, [filteredPokemon])




  // SEARCH POKEMON RESULTS

  // FILTER POKEMON RESULTS




  return (
    <div className="pokemon__display-area">
      <GetFilteredPokemon 
         pokemons={pokemons}
         amount={20} 
         offset={offset} 
         filteredPokemon={filteredPokemon} 
         setFilteredPokemon={setFilteredPokemon}
       />
       
      {cards.map((card, i) => {
        const pokemon = card[i];
        
        return (
            <PokemonCard 
               key={pokemon.id} 
               name={pokemon.name}
          />
      })}
    </div>
  )
}

【讨论】:

    猜你喜欢
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2022-12-06
    • 2016-09-14
    • 1970-01-01
    • 2023-02-16
    • 1970-01-01
    相关资源
    最近更新 更多