React Hooks:如何更新状态中嵌套数组内的downloads属性?
更新React嵌套数组状态中的downloads属性
你当前的React状态结构如下:
const [record, setRecord] = useState([ { name: "Pink Floyd", rank: 1, songs: [ { name: "A", year: "1970", downloads: "10", }, { name: "B", year: "1980", downloads: "20", }, { name: "C", year: "1990", downloads: "5", }, ], }, { name: "Led Zeppelin", rank: 2, songs: [ { name: "D", year: "1965", downloads: "25", }, { name: "E", year: "1975", downloads: "65", }, { name: "F", year: "1985", downloads: "90", }, ], }, ]);
你已经掌握了更新外层rank属性的方法:
setRecord(prevRecord => prevRecord.map((el) => el.name == "someName" ? { ...el, rank: "someRank" } : el ) );
要更新嵌套在songs数组中的downloads属性,核心思路是保留状态的不可变性,通过两层map遍历完成更新:
示例:更新指定歌手的指定歌曲下载量
比如要把Pink Floyd的歌曲"A"的downloads改为"100",可以这样写:
setRecord(prevRecord => prevRecord.map(artist => { // 匹配目标歌手 if (artist.name === "Pink Floyd") { // 遍历该歌手的歌曲数组,更新目标歌曲 const updatedSongs = artist.songs.map(song => { if (song.name === "A") { // 展开原歌曲对象,替换downloads属性 return { ...song, downloads: "100" }; } // 非目标歌曲直接返回原对象 return song; }); // 展开原歌手对象,替换songs数组 return { ...artist, songs: updatedSongs }; } // 非目标歌手直接返回原对象 return artist; }) );
通用化写法
如果需要频繁更新不同歌曲的下载量,可以封装成一个复用函数:
const updateSongDownloads = (targetArtist, targetSong, newDownloadCount) => { setRecord(prevRecord => prevRecord.map(artist => { if (artist.name !== targetArtist) return artist; return { ...artist, songs: artist.songs.map(song => song.name === targetSong ? { ...song, downloads: newDownloadCount } : song ) }; }) ); }; // 调用示例:更新Led Zeppelin的歌曲"F"的下载量为"95" updateSongDownloads("Led Zeppelin", "F", "95");
关键说明
- 全程使用展开运算符(
...)创建新对象/数组,避免直接修改原状态(React状态是不可变的,直接修改会导致组件无法正确重新渲染) - 通过两层
map分别处理外层歌手数组和内层歌曲数组,精准定位需要更新的目标元素
内容的提问来源于stack exchange,提问作者Zahir Masoodi
相关产品推荐
相关产品推荐

