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

如何移除React音乐库筛选下拉菜单中的重复选项

解决React音乐库筛选下拉菜单重复项问题

当前第二个筛选下拉菜单直接遍历所有歌曲生成选项,导致同一类别下的重复值多次出现。可以通过以下方案去除重复项:

实现思路

利用Set数据结构自动去重的特性,提取指定筛选类别下的唯一值,再转换为数组渲染选项。同时用useMemo缓存计算结果,避免不必要的重复计算,提升组件性能。

修改后的完整代码

import React, { useState, useEffect, useMemo } from 'react';
import axios from 'axios';

function App() {
  const [songs, setSongs] = useState([])
  const [title, setTitle] = useState('')
  const [artist, setArtist] = useState('')
  const [album, setAlbum] = useState('')
  const [genre, setGenre] = useState('')
  const [date, setDate] = useState('')
  const [category, setCategory] = useState('')
  const [choice, setChoice] = useState([])

  useEffect(() => {
    getAllSongs()
  }, []);

  async function getAllSongs() {
    const response = await axios.get('http://127.0.0.1:8000/api/music/');
    const allSongs = response.data
    setSongs(allSongs)
  }

  async function postSong(event){
    event.preventDefault()
    const songObject = {title, artist, album, 'release_date': date, genre}
    await axios.post('http://127.0.0.1:8000/api/music/', songObject)
    // 新增歌曲后刷新列表,保证数据同步
    getAllSongs()
  }

  const handleTitleChange = (event) => setTitle(event.target.value)
  const handleArtistChange = (event) => setArtist(event.target.value)
  const handleAlbumChange = (event) => setAlbum(event.target.value)
  const handleGenreChange = (event) => setGenre(event.target.value)
  const handleDateChange = (event) => setDate(event.target.value)
  const handleCategoryChange = (event) => setCategory(event.target.value)
  
  const handleChoiceChange = (event) => {
    setChoice(songs.filter((song) => song[category] === event.target.value))
  }

  // 缓存去重后的选项数组,仅当songs或category变化时重新计算
  const uniqueOptions = useMemo(() => {
    if (!category) return [];
    return [...new Set(songs.map(song => song[category]))];
  }, [songs, category]);

  const displaySongs = (songsArr) => {
    return songsArr.map((song) =>(
      <tr key={song.id || `${song.title}-${song.release_date}`}>
        <td>{song?.title}</td>
        <td>{song?.artist}</td>
        <td>{song?.album}</td>
        <td>{song?.genre}</td>
        <td>{song?.release_date}</td>
      </tr>
    ))
  }

  return (
    <div>
        <h1>Music Library</h1>
        <label htmlFor='songs'>Filter: </label>
        <select name='categories' value={category} onChange={handleCategoryChange}>
          <option value="">Select your category</option>
          <option value='title'>Title</option>
          <option value='artist'>Artist</option>
          <option value='genre'>Genre</option>
          <option value='album'>Album</option>
          <option value='release_date'>Release Date</option>
        </select>
        <select name='choice' onChange={handleChoiceChange}>
          <option value="">Select the {category}</option>
          {/* 使用去重后的数组渲染选项 */}
          {uniqueOptions.map(value => (
            <option key={value} value={value}>{value}</option>
          ))}
        </select>
        <table>
          <tr>
            <th>Title</th>
            <th>Artist</th>
            <th>Album</th>
            <th>Genre</th>
            <th>Release Date</th>
          </tr>
          {choice.length > 0 ? displaySongs(choice): displaySongs(songs)}
        </table>
        <form>
          <label>Title </label>
          <input type='text' value={title} onChange={handleTitleChange}/>
          <label> Artist </label>
          <input type='text' value={artist} onChange={handleArtistChange}/>
          <label> Album </label>
          <input type='text' value={album} onChange={handleAlbumChange}/>
          <label> Genre </label>
          <input type='text' value={genre} onChange={handleGenreChange}/>
          <label> Release Date </label>
          <input type='date' value={date} onChange={handleDateChange}/>
          <button onClick={postSong}>Add New Song</button>
        </form>
    </div>
  );
}

export default App;

关键修改说明

  1. 去重逻辑:通过new Set(songs.map(song => song[category]))提取指定类别的所有值并自动去重,再用扩展运算符[...]将Set转换为可遍历的数组。
  2. 性能优化:使用useMemo缓存去重后的选项数组,仅当songs或category变化时重新计算,避免每次渲染重复执行去重操作。
  3. React key修复:为<tr>和<option>添加唯一key,消除React控制台的列表项警告。
  4. 数据同步:新增歌曲后调用getAllSongs()刷新列表,确保新增内容能立即在筛选选项中显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:07:08