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

React开发Pokedex宝可梦图鉴 实现添加/移除收藏列表功能求助

核心问题梳理

你当前的收藏状态只存储在PokemonFav组件内部,属于组件私有状态,详情页、导航栏等其他组件无法访问和修改,所以无法实现跨页面的收藏交互。

具体改造步骤

1. 新建全局收藏Context实现状态共享

在src目录下新建FavContext.js文件,代码如下:

import { createContext, useContext, useState, useEffect } from 'react';

const FavContext = createContext();

export function FavProvider({ children }) {
  // 初始化从localStorage读取收藏列表,避免刷新丢失
  const [favList, setFavList] = useState(() => {
    const saved = localStorage.getItem('pokemonFav');
    return saved ? JSON.parse(saved) : [];
  });

  // 收藏列表变更时自动同步到localStorage
  useEffect(() => {
    localStorage.setItem('pokemonFav', JSON.stringify(favList));
  }, [favList]);

  // 切换收藏状态:已收藏则移除,未收藏则添加
  const toggleFav = (pokemon) => {
    setFavList(prev => {
      // 用宝可梦id作为唯一判断标准,避免重名问题
      const isExist = prev.find(item => item.id === pokemon.id);
      if (isExist) {
        return prev.filter(item => item.id !== pokemon.id);
      } else {
        return [...prev, pokemon];
      }
    })
  }

  // 判断某个宝可梦是否已收藏
  const isFavorited = (pokemonId) => {
    return favList.some(item => item.id === pokemonId);
  }

  return (
    <FavContext.Provider value={{ favList, toggleFav, isFavorited }}>
      {children}
    </FavContext.Provider>
  )
}

// 自定义hooks,方便其他组件调用context
export function useFav() {
  return useContext(FavContext);
}

2. 全局注入Context

修改App.jsx,用FavProvider包裹所有路由组件:

import { FavProvider } from './FavContext';

function App() {
  // 你原有App组件的逻辑不变,只需要在最外层包FavProvider
  return (
    <FavProvider>
      {/* 你原有所有的路由、导航栏、页面组件都放在这里 */}
    </FavProvider>
  )
}

3. 修改详情页收藏按钮逻辑

在宝可梦详情页组件中引入useFav,修改按钮代码:

import { useFav } from '../FavContext';

// 组件内部逻辑
function PokemonDetail() {
  // 你原有获取当前宝可梦数据的逻辑不变,假设当前宝可梦数据存在currentPokemon变量里
  const { toggleFav, isFavorited } = useFav();
  const isFav = isFavorited(currentPokemon.id);

  return (
    {/* 其他详情内容不变 */}
    <button onClick={() => toggleFav(currentPokemon)}>
      {isFav ? '取消收藏' : '添加收藏'}
    </button>
  )
}

如果要在宝可梦列表卡片pokemoncard.js上加收藏按钮,逻辑和详情页完全一致,直接调用toggleFav和isFavorited方法即可。

4. 改造你的PokemonFav组件

直接从全局Context获取收藏列表渲染,新增移除功能:

import { useFav } from '../FavContext';

function PokemonFav(){
  const { favList, toggleFav } = useFav();

  return(
    <div>
      <h2>收藏列表</h2>
      {favList.length === 0 ? (
        <p>暂无收藏的宝可梦</p>
      ) : (
        <ul>
          {favList.map(pokemon=> (
            <li key={pokemon.id}>
              {pokemon.name}
              <button onClick={() => toggleFav(pokemon)}>移除收藏</button>
            </li>
          ))}
        </ul>
      )}
    </div>
  )
}
export default PokemonFav;

5. 导航栏收藏入口

导航栏直接添加跳转到收藏页面的路由即可,收藏页已经可以直接读取全局的收藏列表渲染。

内容的提问来源于stack exchange,提问作者Yasmins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:48:02