React useState数组移除异常:Playlist应用删除歌曲仅文本消失
播放列表歌曲移除后卡片残留问题的修复方案
问题描述
开发自定义播放列表应用时,搜索结果的歌曲可正常添加至播放列表,但点击移除按钮时,仅歌曲名、歌手、专辑文本消失,歌曲卡片仍保留在列表中。
问题根源及修复步骤
1. App组件中onRemove函数的数组处理错误
原代码里onRemove把filter返回的数组又套了一层数组,导致playlistTracks变成二维数组,渲染时出现空卡片项。
修正前的onRemove:
const onRemove = (e) => { console.log(playlistTracks); setPlaylistTracks([playlistTracks.filter((song) => song.id == e.id)]); };
修正后的onRemove:
const onRemove = (track) => { setPlaylistTracks(prevTracks => prevTracks.filter(song => song.id !== track.id)); };
说明:
filter本身返回新数组,无需额外用[]包裹- 用函数式更新
prevTracks,确保拿到最新状态值 - 用
!==替代==,避免隐式类型转换的潜在问题
2. Tracklist组件中key的错误生成方式
原代码每次渲染都随机生成key,导致React无法正确识别列表项变化,移除后DOM更新异常。
修正前的Tracklist map部分:
{props.tracks.map((track) => { return ( <Track key={generateKey()} track={track} onAdd={props.onAdd} onRemove={props.onRemove} string={props.string} /> ); })}
修正后的Tracklist map部分:
{props.tracks.map((track) => { return ( <Track key={track.id} track={track} onAdd={props.onAdd} onRemove={props.onRemove} string={props.string} /> ); })}
说明:
- 用歌曲的唯一
id作为key,React能通过key准确追踪列表项状态,确保移除后DOM正确更新 - 删除Tracklist中冗余的
generateKey函数,歌曲本身已有唯一id
完整修正后的代码片段
App组件修正后
import { useState } from "react"; import SearchBar from "./SearchBar"; import SearchResults from "./SearchResults"; import Playlist from "./Playlist"; import styles from "../Styles/App.module.css"; const generateKey = () => { let num = ""; let characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; const chars = characters.length; for (let i = 0; i < 5; i++) { num += characters.charAt(Math.floor(Math.random() * chars)); } return num; }; function App() { const [playlistTracks, setPlaylistTracks] = useState([]); const [searchResults, setSearchResults] = useState([ { song: "Go Baby", artist: "Lupe", album: "Food and Liqour", id: generateKey(), }, { song: "Demon Days", artist: "Gorillaz", album: "Self titled", id: generateKey(), }, ]); const onAdd = (track) => { setPlaylistTracks((prevTracks) => [...prevTracks, track]); }; const onRemove = (track) => { setPlaylistTracks(prevTracks => prevTracks.filter(song => song.id !== track.id)); }; return ( <div id={styles.app}> <header> <h1>Spotify Playlist App</h1> </header> <SearchBar /> <main> <SearchResults searchResults={searchResults} onAdd={onAdd} /> <Playlist playlistTracks={playlistTracks} name="playlist" onRemove={onRemove} /> </main> </div> ); } export default App;
Tracklist组件修正后
import React from "react"; import Track from "./Track"; function Tracklist(props) { return ( <div> {props.tracks.map((track) => { return ( <Track key={track.id} track={track} onAdd={props.onAdd} onRemove={props.onRemove} string={props.string} /> ); })} </div> ); } export default Tracklist;
内容的提问来源于stack exchange,提问作者shimmyshimmyya7347
相关产品推荐
相关产品推荐

