反应 - 地图功能?

时间:2021-05-14 00:40:12

标签: javascript reactjs axios

这个想法是获取用户在数据库中使用的卡片,并与屏幕上收听的所有卡片进行比较。基本上用户不应该看到他已经使用过的卡片。

const loadSaveInvestments = async (
    _req: express.Request,
    res: express.Response
  ) => {
    const findSaveInvestments = await prisma.investmentSave.findMany({
      select: {
        investment_id: true,
      },
    });
    if (!findSaveInvestments) throw new HttpException(400, SAVE_INVEST_MISSING);
    res.send(findSaveInvestments);
  };

所以,我将发送所有保存的投资卡。现在,在 React 中 - 我正在从服务中获取发送的数据(所有卡片和保存的卡片)

const fetchUserSaveInvestments = async () => {
  const res = await axios.get(`${baseURL}/investments-save`);
  return res;
};
const [cards, setCards] = useState([]);
const [saveCards, setSaveCards] = useState([]);

useEffect(() => {
    setLoading(true);

    investService.fetchUserSaveInvestments().then((res) => {
      setSaveCards(res.data);
    });

    investService.fetchCards().then((res) => {
      setCards(res.data.investments);
      setLoading(false);
    });

现在 - 主要部分。我只想在卡片的 id 不在保存卡片状态时映射卡片,所以我尝试过类似的东西..我已经标记了我有点卡住的点,我的意思是,我应该创建类似 double 的东西吗?地图还是什么?不知道我是否朝着正确的方向前进。

      <div className={classes.CardsContainer}>
        <div className={classes.CardsSelector}>
          {loading && <p> its loading </p>}
          {!loading && (
            <>
              {cards
                .filter(
                  (card) => card.id !== saveCards.?????.investments_id
                )
                .map((card) => (
                  <Card
                    {...card}
                    handleClick={() => handleChooseCard(card)}
                  />
                ))}
            </>
          )}
        </div>

提前致谢。

2 个答案:

答案 0 :(得分:0)

我会尝试使用 Set 来跟踪保存的卡 ID,因为它提供了 O(1) 时间复杂度查找(更快,更好而不是为每个过滤器候选搜索另一个数组)。

const [loading, setLoading] = useState(false)
const [cards, setCards] = useState([])
const [saveCards, setSaveCards] = useState(new Set())

useEffect(async () => {
  setLoading(true);

  const { data: savedCards } = await investService.fetchUserSaveInvestments()
  const savedCardIds = savedCards.map(({ investments_id }) => investments_id)
  setSaveCards(new Set(savedCardIds))

  const { data: { investments: cards } } = await investService.fetchCards()
  setCards(cards)
  setLoading(false)
}, [])

然后您可以使用备忘录进行过滤

const myCards = useMemo(() => cards.filter(({ id }) => !saveCards.has(id)), [cards, saveCards])
{myCards.map(card => (
  <Card
    {...card}
    handleClick={() => handleChooseCard(card)}
  />
))}

答案 1 :(得分:0)

只需声明以下状态:

const [investmentsIds, setInvestmentIds] = useState([]);

在此处再添加几行代码:

investService.fetchUserSaveInvestments().then((res) => {
   setSaveCards(res.data);
   let savedCardIds = [];
   /* push investment_id in an array */
   res.data.forEach((value)=>{
       savedCardIds.push(value.investments_id);
   })
   setInvestmentIds(savedCardIds);
});

您的 JSX:

<div className={classes.CardsContainer}>
   <div className={classes.CardsSelector}>
       {loading && <p> its loading </p>}
       {!loading && (
          {cards.map((card) => (
            {investmentsIds.includes(card.id) && 
              <Card {...card}
              handleClick={() => handleChooseCard(card)}/>
            }
          ))}
       )}
   </div>
</div>