【问题标题】:React Hooks populate arrayReact Hooks 填充数组
【发布时间】:2020-04-15 08:44:15
【问题描述】:

场景:我有一个对象数组来填充列表。当用户单击其中一个项目时,该项目需要在视觉上被“选中”,我认为会被推送到一个名为“selectedList”的新数组中。如果用户单击另一个未选中的项目,该项目将被选中并保持先前​​的选择。如果用户单击选定项目,则需要将选定状态切换为未选定并在 selectedList 数组中删除。

我对此的想法是先添加一个由默认对象组成的 selectedList 数组,然后当用户单击其他对象时,将它们推送到数组中。到目前为止我有这个。

如何切换数组中的选择以及如何检查 selectedList 数组,以便告诉“FundCard”组件将其选中状态设置为 true,以便在视觉上更新为选中状态?

这是我目前所拥有的:

import React, {useState, useEffect} from 'react';
import styled from 'styled-components';
import FundCard from '../FundCard'

const FundDLWrap = styled.ul`
  margin: 0;
  padding: 0;
  list-style-type: none;
  border-left: 1px solid #e6e6e6;
  margin-top: -40px;
  height: 1007px;
  overflow-y: scroll;
  li {
    &:hover {
      cursor: pointer;
    }
  }
`

const FundDetailList = ({data, fundID}) => {
  const [selectedList, setSelectedList] = useState([fundID]);

  const listSelection = (i) => {
    setSelectedList([...selectedList, i]);
  }

  console.log("selected list", selectedList);

  return (
    <FundDLWrap>
      {data.map((item, i) => {
        // one item must always be selected - the item ID the user came from 
        const selected = fundID === i;

        return (
          <li key={i} onClick={() => listSelection(i)}>
            <FundCard data={item} vertical={true} selected={selected} />
          </li>
        );
      })}
    </FundDLWrap>
  )
}

export default FundDetailList;

这是其中一个数据对象的样子:

{
    saved: false,
    name: 'Title here',
    dailyChange: "3.52",
    inc: true,
    price: '132.42',
    priceDate: '11 Mar 2020',
    volRating: 1,
  },

请注意数据是外部的,没有保持状态。

【问题讨论】:

  • 您能否为此使用 codepen 或 codesandbox 创建一个small demo 来显示正在发生的问题。
  • 您需要做的不仅仅是检查索引是否在处理程序的列表中,然后将其过滤掉或将其推入吗?例如setSelectedList(selectedList.includes(i) ? selectedList.filter(j =&gt; j !== i) : [... selectedList, i])
  • @TomFinney 这太棒了!是的,这是其中的一部分。然后我需要能够检查 selectedList 中的活动项目,以便我可以将 FundCard 设置为活动 - 查看所选道具的 FundCard 组件 - 这会将它们设置为“被选中”。
  • 您可以使用处理程序中的相同逻辑,例如 selected={selectedList.includes(i)} ?

标签: javascript reactjs react-hooks


【解决方案1】:

如果指定的索引iselectedList中,则将其过滤掉,否则,将其附加到数组的副本中。

在返回中使用相同的selectedList.includes(i) 来设置FundCardselected 属性。

const FundDetailList = ({data, fundID}) => {
  // Don't populate index 0 with fundID, it'll get matched in the map function
  const [selectedList, setSelectedList] = useState([]);

  const listSelection = (i) => {
    setSelectedList(
      selectedList.includes(i) 
        ? selectedList.filter(index => index !== i) 
        : [... selectedList, i]
    );
  }

  return (
    <FundDLWrap>
      {data.map((item, i) => {
        // one item must always be selected - the item ID the user came from 
        const selected = selectedList.includes(i) || fundID === i;

        return (
          <li key={i} onClick={() => listSelection(i)}>
            <FundCard data={item} vertical selected={selected} />
          </li>
        );
      })}
    </FundDLWrap>
  )
}

【讨论】:

  • 只是一个简短的说明 - 我在选择变量的 selectedList.includes(i) 时遇到问题。列表中的第一项始终被选中,因为fundID 在 selectedList 数组中设置了 0 位置。 fundID 可以是 0 - 9 之间的任何数字。fundID 设置第一个原始位置。关于如何解决这个问题的任何想法?
  • 我认为 notfundID 预先填充selectedList 会起作用,然后数据映射的索引i 可以与传递给的索引匹配onClick 回调,检查fundID === i 也只是一个附加条件。这样fundID 就不会与selectedList 中的任何索引耦合。
猜你喜欢
  • 2021-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 2015-07-13
  • 2019-07-28
  • 2012-08-04
相关资源
最近更新 更多