You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js卡片组件收藏按钮无法触发API调用问题求助

你的场景完全适配SWR,用SWR可以完美解决多页面同个商品收藏状态同步的问题,先排查现有代码的问题,再给出接入SWR后的完整实现:

现有代码问题排查

  • 请求方法颠倒:新增收藏应该发POST,取消收藏发DELETE,你当前两个方法的method配置完全写反了
  • axios参数错误:axios请求配置中,请求体的字段名是data不是body,你写的body字段不会被axios识别,请求不会携带商品ID参数
  • session未获取:代码中直接使用session.token但没有前置获取session的逻辑,如果用next-auth的话需要先调用useSession()钩子拿到登录态
  • 状态更新逻辑不合理:点击后直接修改收藏状态,不管请求是否成功,一旦接口报错会出现前端显示和后端实际状态不一致的问题
  • 多组件状态不同步:每个Card组件单独维护收藏状态,同一个商品在不同页面的Card组件状态无法同步,这正是SWR的适用场景。

接入SWR后的实现方案

SWR会基于请求key全局缓存数据,所有引用同一个key的组件都会自动同步状态,不需要自己额外做状态管理。

第一步:安装依赖

npm install swr next-auth (如果已经装了可以跳过)

第二步:修改后的完整Card组件代码

import React from "react"
import Link from 'next/link'
import useSWR, { mutate } from 'swr'
import { useSession } from 'next-auth/react'
import Styles from "./card.module.scss"
import axios from 'axios'

// 封装axios请求器给SWR用
const fetcher = (url, token) => axios.get(url, {
  headers: { Authorization: `Bearer ${token}` }
}).then(res => res.data)

export default function Card(props) {
  const { data: session } = useSession()
  // 全局缓存当前用户的收藏列表,所有Card组件共用这份数据
  const { data: favorites = [] } = useSWR(
    session ? [`${process.env.NEXT_PUBLIC_BASE_API}/favorites`, session.user.token] : null,
    fetcher
  )
  // 直接从全局收藏列表判断当前商品是否被收藏,不需要单独维护state
  const isFavorited = favorites.some(item => item.advert === props["@id"])

  const toggleFavorite = async () => {
    if (!session) return // 未登录直接返回
    try {
      if (isFavorited) {
        // 取消收藏发DELETE请求
        await axios({
          method: 'DELETE',
          url: `${process.env.NEXT_PUBLIC_BASE_API}/favorites`,
          headers: {
            Authorization: "Bearer " + session.user.token,
          },
          data: {
            advert: props["@id"]
          }
        });
      } else {
        // 新增收藏发POST请求
        await axios({
          method: 'POST',
          url: `${process.env.NEXT_PUBLIC_BASE_API}/favorites`,
          headers: {
            Authorization: "Bearer " + session.user.token,
          },
          data: {
            advert: props["@id"]
          }
        });
      }
      // 请求成功后更新SWR全局缓存,所有用到收藏列表的组件都会自动同步状态
      mutate([`${process.env.NEXT_PUBLIC_BASE_API}/favorites`, session.user.token])
    } catch (error) {
      if (error.response) {
        throw new Error(error.response.data.message)
      }
    }
  }

  return (
    <div className={Styles.card}>
      <Link href={"/annonce?id="+props.id} passHref>
        <a className={Styles.imageCard}  style={{backgroundImage: `url(${props.imageSrc})`}}>
          <p className={Styles.localisationCard}><span className="material-icons">location_on</span>{props.localisation}</p>
        </a>
      </Link>
      <div className={`${Styles.favCard} ${isFavorited ? Styles.active : ''}`} onClick={toggleFavorite}></div>
      <p className={Styles.titleCard}>{props.title}</p>
      <p className={Styles.pricesCard}><span className="material-icons-outlined">local_offer</span>Prix : {props.prices}</p>
      <p className={Styles.eligibilitesCard}><span className="material-icons-outlined">check_circle</span>Eligibilité ({props.eligibilities})</p>
    </div>
  )
}

改动说明

  • 用SWR全局缓存当前用户的收藏列表,所有Card组件共享同一份数据,同一个商品在任何页面的收藏状态都会自动同步
  • 修正了请求方法和axios参数的错误
  • 登录态通过next-auth的useSession钩子获取,避免session未定义的问题
  • 只有请求成功后才会更新缓存状态,避免前端和后端状态不一致
  • 去掉了冗余的本地favoris状态,直接从全局收藏列表判断是否已收藏

内容的提问来源于stack exchange,提问作者Mélanie Croce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 12:45:04