Reactjs,将数据(id)从一个组件传递到另一个组件以下载歌曲



嗨,我是Reactjs的新手,正在一个音乐网站的项目中练习。但有一个问题让我很纠结。有一个歌曲页面,我应该在那里展示一些歌曲卡片。

import React from 'react'
import SongCard from '../components/SongCard';
import { songsList } from '../components/songsList';
//this is first object of the songsList file which i hard coded instead of using api:
export const songsList =[
{
id : 1,
url : './components/Player/Songs/Homayoun Shajarian - Souvashoun.mp3',
image : require('../assets/Souvashoun.jfif').default,
name : 'x',
singer : 'y',
style :'z',
lyrics :'v',
source : './Palyer/Songs/Homayoun Shajarian - Souvashoun.mp3'

}];
export default function Songs() {
return(
<div>
<SongCard className='col-md-6' id={songsList[0].id} image={songsList[0].image} name={songsList[0].name} singer={songsList[0].singer}/><br/>
<SongCard className='col-md-6' id={songsList[1].id} image={songsList[1].image} name={songsList[1].name} singer={songsList[1].singer}/><br/>
<SongCard className='col-md-6' id={songsList[2].id} image={songsList[2].image} name={songsList[2].name} singer={songsList[2].singer}/><br/>
</div>
);
}

在我将在下面附上代码的歌曲卡中,有一个按钮旨在将我们引导到下载音乐页面,以便下载点击该按钮的特定歌曲:

import React from 'react'
import {Card, Button} from 'react-bootstrap';
import styled from 'styled-components';
import {BrowserRouter as Router} from 'react-router-dom';
function SongCard(props){ 
const id = this.props.id;
this.props.history.push({
pathname: '/downloadMusic',
search: '?query=downloadMusic',
state: { data: id }
})
return(

<Styles>
<Router>
<Card style={{ width: '18rem'}} className="cardbg shadow" text="white">
<Card.Img variant="top" src={props.image} className="img-fluid" />
<Card.Body className="text-center">
<Card.Title>آهنگ {props.name}</Card.Title>
<Card.Text>خواننده {props.singer}
</Card.Text>


<Button  href="/DownloadMusic/:id" className="btn btn-outline-dark">go to download page</Button>


</Card.Body>
</Card> 
</Router>
</Styles>

);
}
export default SongCard;

最后这是下载音乐的最后一页。这里还应该有一张卡片,其中包含关于特定歌曲和最终下载按钮的信息。

import React from 'react';
import { songsList } from './songsList';
import DownloadCard from './DownloadCard';
import AudioPlayer from './Player/AudioPlayer';
function DownloadMusic() {
const id = this.props.location.state.data;
const song = songsList.find(item => item.id === id);
return(
<div>
<DownloadCard className='col-md-6' id= {song.id} image={song.image} name={song.name} singer={song.singer}/><br/>
<AudioPlayer/>
</div>
);
}
export default DownloadMusic;

我想要的是将在歌曲页面中点击的特定歌曲的id和url发送到下载音乐页面,并在卡片中显示歌曲列表中的信息。我已经尝试了很多方法,比如使用state、useParams((。。。但没有一个对我有用。而且我不想把所有道具都寄出去,因为我知道这不是最好的做法。那么我做错了什么?

希望我已经分享了足够的信息。任何帮助都将不胜感激。

您要做的是映射歌曲数组,就像这个

import React from 'react'
import React from 'react'
import SongCard from '../components/SongCard';
import { songsList } from '../components/songsList';
//this is first object of the songsList file which i hard coded instead of using api:
const songsList =[
{
id : 1,
url : './components/Player/Songs/Homayoun Shajarian - Souvashoun.mp3',
image : require('../assets/Souvashoun.jfif').default,
name : 'x',
singer : 'y',
style :'z',
lyrics :'v',
source : './Palyer/Songs/Homayoun Shajarian - Souvashoun.mp3'

}];
export default function Songs() {


return(

<div>
{
songsList.map((song, idx) => {
return     <SongCard key={idx} className='col-md-6' id={song.id} image={song.image} name={song.name} singer={song.singer}/>
})

}    
</div>

);
}

好吧,经过长时间的努力,我终于找到了一种方法!如果有人需要,我会在这里分享。

因此,在SongCard.js中,我使用useHistory((和导航函数来保存id并导航到downloadMusic页面,也在按钮使用的导航函数的onClick属性中:

import React from 'react'
import {Card, Button} from 'react-bootstrap';
import styled from 'styled-components';
import {BrowserRouter as Router, useHistory} from 'react-router-dom';

function SongCard(props){ 
//navigating and saving id
const history = useHistory()
const navigate = (id) => {
history.push(`/downloadMusic/${id}`)
}
return(

<Styles>
<Router>
<Card style={{ width: '18rem'}} className="cardbg shadow" text="white">
<Card.Img variant="top" src={props.image} className="img-fluid" />
<Card.Body className="text-center">
<Card.Title>آهنگ {props.name}</Card.Title>
<Card.Text>خواننده {props.singer}
</Card.Text>

//make sure you add onClick attribute!
<Button  onClick={() => navigate(props.id)} className="btn btn-outline-dark">download</Button>
</Card.Body>
</Card> 
</Router>
</Styles>

);
}
export default SongCard;

然后在DownloadMusic.js中,我使用useRouteMatch((访问了id param,这个id是字符串,所以我在下一步中将其转换为数字。最后,通过使用.find((方法,我找到了被点击的特定歌曲!

import React from 'react';
import { songsList } from './songsList';
import DownloadCard from './DownloadCard';
import AudioPlayer from './Player/AudioPlayer';
import { useRouteMatch } from "react-router-dom";

function DownloadMusic() {
//getting id param
const {
params: { id },
} = useRouteMatch('/downloadMusic/:id');
//converting the string id to number:
const num = Number(id);
//finding the song with song.id= num
const song = songsList.find(item => item.id === num);

return(
<div>
<DownloadCard className='col-md-6' 
id= {song.id} 
url= {song.url} 
image={song.image} 
name={song.name} 
singer={song.singer}
/><br/>
<AudioPlayer id = {song.id}/>
</div>
);
}
export default DownloadMusic;

只要小心id的类型,它必须是数字。这个小家伙花了我很长时间。:(祝你好运!

您可以在歌曲卡片页面中创建这样的函数

const onSongCardClick = () => {
history.push({
pathname: '/downloadMusic',
state: {id: this.props.id, url: this.props.url} 
})
}
...
...
<Button onclick="onSongCardClick()" className="btn btn-outline-dark">go to download page</Button>

并在下载音乐页面中获取这些值

const { id, url } = this.props.location.state

还将url作为道具从歌曲页面传递到歌曲卡

最新更新