【问题标题】:How to delete a card from a list of cards (using API to extract Github user information onto a card that is presented in a list)?如何从卡片列表中删除卡片(使用 API 将 Github 用户信息提取到列表中显示的卡片上)?
【发布时间】:2020-06-21 15:19:20
【问题描述】:

这是一个 React 项目,它使用 API 创建一张卡片,展示 Github 用户信息。目前我正在每张卡上实现一个删除按钮,该按钮将删除该特定卡。您可以通过clicking here. 在代码沙箱上试用该应用程序。使用说明:输入任意“Github”用户名,点击添加卡片。

点击添加卡片后,用户信息将被提取到卡片中,然后存储在卡片列表中。这有一个可识别的密钥。但是当点击删除时,当前所有的卡片都被删除,而不是删除相应的卡片到按下删除按钮的位置。 (我已经排除了表单组件以使其更易于阅读)。

不确定我是否错误地使用了拼接或没有正确声明卡片密钥?

function App() {
  const [cards, setCards] = useState([]);

  const addNewCard = cardInfo => {
    setCards(cards.concat(cardInfo));
  };

  const removeCard = key => {
    setCards(cards.splice(key, 0))
  }

  return (
    <div>
      <Form onSubmit={addNewCard} />
      <CardList
        cards={cards}
        handleClick={removeCard}
      />
    </div>
  );
}

const CardList = props => (
  <div>
    {props.cards.map((card, index) => (
      <Card {...card} key={index} handleClick={props.handleClick} />
    ))}
  </div>
);

const Card = props => {
  return (
    <div style={{ margin: "1em" }}>
      <img alt="avatar" style={{ width: "70px" }} src={props.avatar_url} />
      <div>
        <div style={{ fontWeight: "bold" }}>{props.name}</div>
        <div>{props.blog}</div>
        <a href={props.html_url}>{props.html_url}</a>
        <button onClick={props.handleClick}>Delete</button>
      </div>
    </div>
  );
};

【问题讨论】:

  • 只是快速查看您的代码,密钥似乎未定义或至少不是您想要的,因为密钥是卡的道具,并且您没有使用卡中的 id 填充密钥,并且您的删除点击在整个列表中.. 所以.. 它需要一些工作
  • 我认为你是对的,但不确定如何解决这个问题......任何提示或相关示例都会很棒。

标签: javascript reactjs react-hooks react-component


【解决方案1】:

确切地说,您在钩子的上下文中错误地使用了拼接。检查here to know how splice works

splice() 方法在数组中添加/删除项目,并返回删除的项目。

因此,您正在将尝试删除的元素设置为变量。为了保持你原来的逻辑,我建议你使用这样的临时变量:

const removeCard = key => {
   let tempCards = cards;
   const removedCard = tempCards.splice(key, 0); // you can use the removed card if needed
   setCards(tempCards);
}

并且参数键未定义,您必须将此参数传递给您的函数,请参阅documentation

只需对您的代码进行微小的更改,您就可以更改:

 <Card {...card} key={index} handleClick={props.handleClick} />

到这里:

  <Card {...card} key={index} handleClick={() => props.handleClick(index)} />

编辑:当您使用 concat 时,它可能会添加新卡的每个元素。尝试改变这一点:

 setCards(cards.concat(cardInfo));

到这里:

setCards(cards.push(cardInfo));

【讨论】:

  • 感谢您的回复,但您会发现上面的实现结果相同。但是您应用 props.handleClick(index) 的方式非常有趣,可能对“removeCard”的解决方案有用。
  • 好的,我想知道当你用 concat 添加一些东西时变量是什么样子的。也许它正在添加新卡的每个元素。我更新了我的答案。
【解决方案2】:

我的错误是使用拼接而不是切片。由于 splice 会改变原始数组,因此应该避免这种情况。但是通过将数组切片到您要删除的索引,然后您可以从要删除的索引的另一侧切片并将第二个切片连接到第一个切片。

 const removeCard = key => {
    setCards(cards.slice(0, key).concat(cards.slice(key + 1, cards.length)))
  };

您可以在下面找到完整的代码实现:

function App() {
  const [cards, setCards] = useState([]);

  const addNewCard = cardInfo => {
    setCards(cards.concat(cardInfo));
  };

  const removeCard = key => {
     setCards(cards.slice(0, key).concat(cards.slice(key + 1, cards.length)))
  };

  return (
    <div>
      <Form onSubmit={addNewCard} />
      <CardList
        cards={cards}
        handleClick={removeCard}
      />
    </div>
  );
}

const CardList = props => (
  <div>
    {props.cards.map((card, index) => (
      <Card {...card} key={index} handleClick={props.handleClick(index)} />
    ))}
  </div>
);

const Card = props => {
  return (
    <div style={{ margin: "1em" }}>
      <img alt="avatar" style={{ width: "70px" }} src={props.avatar_url} />
      <div>
        <div style={{ fontWeight: "bold" }}>{props.name}</div>
        <div>{props.blog}</div>
        <a href={props.html_url}>{props.html_url}</a>
        <button onClick={props.handleClick}>Delete</button>
      </div>
    </div>
  );
};

【讨论】:

    猜你喜欢
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    • 2021-12-24
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多