如何在React中实现点击收藏按钮将角色名添加至下拉列表
实现角色收藏功能方案
核心思路:状态提升
因为CardCharacters和Navbar需要共享收藏数据,把收藏状态放到它们的共同父组件里,通过props传递状态和操作方法。
1. 父组件改造(以App组件为例)
import { useState } from 'react'; import { CardCharacters } from './CardCharacters'; import { Navbar } from './Navbar'; function App() { // 初始化收藏列表,可从localStorage读取持久化数据 const [favorites, setFavorites] = useState([]); // 切换收藏状态:添加/移除角色 const toggleFavorite = (name) => { setFavorites(prev => { if (prev.includes(name)) { return prev.filter(item => item !== name); } else { return [...prev, name]; } }); }; // 检查角色是否已收藏 const isFavorite = (name) => favorites.includes(name); return ( <div className="App"> {/* 把收藏列表传给Navbar */} <Navbar favorites={favorites} /> {/* 渲染角色卡片,传递收藏相关方法 */} <div className="container"> <div className="row"> {/* 示例:循环渲染角色卡片 */} {charactersData.map(character => ( <CardCharacters key={character.id} id={character.id} name={character.name} onToggleFavorite={toggleFavorite} isFavorite={isFavorite(character.name)} /> ))} </div> </div> </div> ); } export default App;
2. 修改CardCharacters组件
添加点击事件处理,切换心形图标样式:
export const CardCharacters = (props) => { return ( <div className="card col-sm-4 m-2 bg-secondary p-0" style={{ width: "18rem" }}> <img src={starWarsPoster} className="card-img-top" alt="角色海报" /> <div className="card-body"> <h5 className="card-title mb-4">{props.name}</h5> <Link to={"/people/" + props.id}> <button type="button" className="btn btn-primary ms-4">了解更多</button> </Link> <button type="button" className="btn btn-outline-warning ms-4" onClick={() => props.onToggleFavorite(props.name)} > {/* 根据收藏状态切换实心/空心心形 */} <i className={props.isFavorite ? "fas fa-heart" : "far fa-heart"}></i> </button> </div> </div> ) };
3. 修改Navbar组件
动态渲染收藏列表,更新徽章数字:
export const Navbar = (props) => { return ( <nav className="navbar navbar-light bg-dark mb-3 p-0"> <Link to="/"> <img src={starWars} className="img-fluid rounded-start p-3 ms-5" style={{ width: "130px", height: "80px" }} alt="星球大战logo" /> </Link> <div className="dropdown p-3 me-5"> <button className="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> 我的收藏 {/* 动态显示收藏数量 */} <span className="badge bg-secondary ms-2">{props.favorites.length}</span> </button> <ul className="dropdown-menu"> {/* 动态渲染收藏的角色名,没有收藏时显示提示 */} {props.favorites.length === 0 ? ( <li><span className="dropdown-item-text">暂无收藏</span></li> ) : ( props.favorites.map((name, index) => ( <li key={index}><span className="dropdown-item">{name}</span></li> )) )} </ul> </div> </nav> ); };
可选优化:持久化收藏数据
如果希望刷新页面后收藏不丢失,可以用localStorage保存:
// 父组件初始化时读取localStorage const [favorites, setFavorites] = useState(() => { const saved = localStorage.getItem('starWarsFavorites'); return saved ? JSON.parse(saved) : []; }); // 更新收藏时同步到localStorage const toggleFavorite = (name) => { setFavorites(prev => { const newFavorites = prev.includes(name) ? prev.filter(item => item !== name) : [...prev, name]; localStorage.setItem('starWarsFavorites', JSON.stringify(newFavorites)); return newFavorites; }); };
内容的提问来源于stack exchange,提问作者Mw7
相关产品推荐
相关产品推荐

