开发者问题收集

从一个数组中删除对象,同时将其添加到另一个数组 - React hooks

2020-08-17
726

我正在开发一款类似 Tinder 的应用,尝试在单击“喜欢”或“不喜欢”按钮时从数组中删除当前卡片并转到下一张卡片。同时,我尝试将卡片添加到新数组(喜欢或不喜欢的列表)。将对象添加到新数组似乎可行(尽管存在延迟,并且需要单击按钮两次 - 这也需要排序),但只要我尝试将其从当前数组中删除,它就会崩溃。

我尝试查看此解决方案: 使用钩子(useState)从数组中删除对象 ,但无论我尝试什么,我都只会得到 “TypeError:无法读取未定义的属性‘target’” 。我遗漏了什么?

这是代码:

import React, { useState, useEffect } from 'react';
import { Card, Button, Container } from 'react-bootstrap';

const url = 'https://swiperish-app.com/cards';

const SwiperCard = () => {
  const [cardData, setCardData] = useState([]);
  const [likedItem, setLikedItem] = useState([]);


  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(cardData => setCardData(cardData))
  });

  const handleRemoveItem = (event) => {
    const name = event.target.getAttribute("name")
    setCardData(cardData.filter(item => item.id !==name));  
  };

  const likedCards = (itemId, itemImg, ItemTitle) => {
    let likedArr = [...likedItem];
    setLikedItem(likedItem => likedItem.concat({itemId, itemImg, ItemTitle}))
    handleRemoveItem();
    console.log(likedArr);
  };

  return (
      <div id="contentView">
        {cardData.map((item, index) => {
          return(
            <Card key={index} className="cardContainer" name={item.id}>
              <Container className="btnContainer">
                <div className="btnWrapper">
                  <Button className="btn" onClick={() => console.log(item.id)}>DISLIKE</Button>
                </div>
              </Container>
              <Container className="cardContentContainer">
                <Card.Img style={{width: "18rem"}}
                  variant="top" 
                  src={item.image} 
                  fluid="true" 
                />
                <Card.Body style={{width: "18rem"}}>
                  <Card.Title className="cardTitle">{item.title.toUpperCase()}</Card.Title>
                  <Card.Subtitle className="cardText">{item.body}</Card.Subtitle>
                </Card.Body>
              </Container>
              <Container className="btnContainer">
                <div className="btnWrapper">
                  <Button className="btn" onClick={() => likedCards(item.id, item.image,item.title) }>LIKE</Button>
                </div>
              </Container>
            </Card>
          )
        })}
      </div>
  );
};

export default SwiperCard;
2个回答

您可以使用

const likedCards = (item) => {
    setLikedItem([...likedItem, item]);
    let filtered = cardData.filter((card) => card.itemId !== item.itemId);
    setCardData(filtered);
  };
在两个数组之间移动卡片。

我建议您添加空数组作为 useEffect 的第二个参数,因为您正在使用 componentDidMount。

作为第二个建议,您可以在获取之前将 Loading 设置为 true,在获取之后将 Loading 设置为 false,以减少渲染中的错误。

Ubeyt Demir
2020-08-17

您正在调用没有参数的 handleRemoveItem ,但该函数正在使用 event 参数执行某些操作,因此您将收到 TypeError。

似乎 handleRemoveItem 实际上只需要知道要移除的项目 ID,因此您可以简化为:

const removeCard = id => {
  setCardData(cardData.filter(item => item.id !== id));
};

const handleLike = (itemId, itemImg, ItemTitle) => {
  setLikedItem([...likedItem, {itemId, itemImg, ItemTitle}]);
  removeCard(itemId);
};

我还注意到,您有时会在调用设置后立即记录状态变量。这行不通。直到下一次渲染时再次调用 useState 时,您才会收到该值,因此如果您想记录状态更改,我会记录在您的渲染函数中,而不是在事件处理程序中。

Jacob
2020-08-18