我正在开发一个音乐库,希望用户能够通过选择歌曲进行过滤。我有一个后端API,其中创建了歌曲对象,包括标题、艺术家、专辑、流派发布日期。我能够创建2个下拉菜单,其中第一个下拉菜单允许用户选择他们想要过滤的类别,例如专辑。第二个下拉菜单应该允许用户根据所选的类别进行选择,但是我在那里有重复的。2我显然不想重复。
import React, { useState, useEffect } 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': title, 'artist': artist, 'album': album, 'release_date': date, 'genre': genre}
const songObject = {title, artist, album, 'release_date': date, genre}
await axios.post('http://127.0.0.1:8000/api/music/', songObject)
}
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))
}
const displaySongs = (songsArr) => {
return songsArr.map((song) =>(
<tr>
<td>{song?.title}</td>
<td>{song?.artist}</td>
<td>{song?.album}</td>
<td>{song?.genre}</td>
<td>{song?.release_date}</td>
</tr>
))
}
// As a developer, I want to display the data (song title, album, artist, genre, and release date) from the API within a table on the frontend.
return (
<div>
<h1>Music Library</h1>
<label for='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>
{songs.map((song) => (
<option>{song[category]}</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' onChange={(event) => handleTitleChange(event)}/>
{/* <input type='text' onChange={function(event) {return handleTitleChange(event)}}/> */}
<label> Artist </label>
<input type='text' onChange={(event) => handleArtistChange(event)}/>
<label> Album </label>
<input type='text' onChange={(event) => handleAlbumChange(event)}/>
<label> Genre </label>
<input type='text' onChange={(event) => handleGenreChange(event)}/>
<label> Release Date </label>
<input type='date' onChange={(event) => handleDateChange(event)}/>
{/* <input type='submit'value='Add New Song'/> */}
<button onClick={(event) => postSong(event)} >Add New Song</button>
</form>
</div>
);
}
export default App;
2条答案
按热度按时间lstz6jyr1#
您需要从对象数组中“提取”唯一类别(歌曲),并将其作为选项列表提供给第二个下拉列表。在JavaScript中有多种方法可以实现这一点。最直接的方法是创建一个新数组
const categories = []
并使用songs.forEach()
循环(read docs)来迭代songs
。在回调类中,将数组推送到categories
,检查它是否还不存在。此外,您还可以检查Array.reduce()
(read more)以获得可能的解决方案。但我会使用以下方法:cs7cruho2#
过滤功能可用于检索与特定类别相关的歌曲。请尝试:
如果你想在第二个下拉列表中设置一个默认值const [category,setCategory] = useState('title ')