Как отобразить элемент массива при открытии модального?
Я начинаю с React, и у меня есть проблема.
Я использую YouTube API, чтобы ловить видео плейлистов. С помощью метода.map я отображаю все миниатюры и заголовки видео на карточках. Когда я нажимаю на карту, я хочу запустить видео (в Reactplayer), "поймав" индекс моего массива (в моем состоянии). Большое спасибо за ответы и советы, которые вы могли бы дать:)
Вот мой код ниже:
import React, { Component } from 'react'
import axios from 'axios';
import posed from 'react-pose';
import ReactPlayer from 'react-player';
import { Card, CardImg, Col, Row, CardTitle, Modal, ModalBody, ModalHeader } from 'reactstrap';
import './videos.css'
const Box = posed.div({
hidden: { opacity: 0 },
visible: { opacity: 1 }
});
class Videos extends Component {
constructor () {
super();
this.state = {
isVisible : true,
videos: [],
resultsDatas: "",
nextPage: "",
previousPage: "",
videoId: "",
search: "",
playing: false,
modal : false
}
}
componentDidMount() {
axios.get('https://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyChOLdIP9GxDMPWjMmEnh6doR5Bdf1sGBk&playlistId=PL3-4jitn5YqtnR_mrYoz_Qb0z7frXZcW6&type=video&showinfo=0&iv_load_policy=3&part=snippet,id&order=date&maxResults=24')
.then((result) => {
this.setState({
videos: result.data.items,
resultsDatas: result.data,
nextPage: result.data.nextPageToken});
console.log(this.state.videos);
this.state.videos.map((item) => {
if(item.snippet.title.length > 38) {
return (item.snippet.title=`${item.snippet.title.slice(0,37)}... `);
}
})
}
)
setTimeout(() => {this.setState({ isVisible: !this.state.isVisible });
}, 400);
}
nextPage = () => {
axios.get(`https://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyChOLdIP9GxDMPWjMmEnh6doR5Bdf1sGBk&playlistId=PL3-4jitn5YqtnR_mrYoz_Qb0z7frXZcW6&type=video&part=snippet,id&order=date&maxResults=24&pageToken=${this.state.nextPage}`)
.then((result) => {
this.setState({
nextPage: result.data.nextPageToken,
previousPage: result.data.prevPageToken,
videos: result.data.items,
resultsDatas: result.data
});
})
}
previousPage = () => {
axios.get(`https://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyChOLdIP9GxDMPWjMmEnh6doR5Bdf1sGBk&playlistId=PL3-4jitn5YqtnR_mrYoz_Qb0z7frXZcW6&type=video&part=snippet,id&order=date&maxResults=24&pageToken=${this.state.previousPage}`)
.then((result) => {
this.setState({
nextPage: result.data.nextPageToken,
previousPage: result.data.prevPageToken,
videos: result.data.items,
resultsDatas: result.data});
})
}
//For search function
inputChange = (event) => {
this.setState({search: event.target.value })
}
playPause = (index) => {
let element = document.getElementById(`play-pause${index}`);
if (element.requestFullscreen) {
this.setState({playing: !this.state.playing})
}
}
toggleModal = () => {
this.setState({
modal: !this.state.modal
});
}
render() {
let mapedVideos = this.state.videos.filter(
(item) => {
return item.snippet.title.toLowerCase().indexOf(this.state.search) !==-1;
}
);
return (
<div>
<Box pose={this.state.isVisible ? 'hidden' : 'visible'}>
<Row className="custom-videos-row mb-5">
{mapedVideos.map((item, index) => {
return (
<Col className="custom-videos-col" lg="3" md="4" sm="6" key={index}>
<Card className="card-wrapper" onClick={() => {this.toggleModal()}}>
<CardImg className="video-thumbnail" src={item.snippet.thumbnails.medium.url} alt="thumb"></CardImg>
<CardTitle className="video-card-title pl-2"><img className="play-picto" src={process.env.PUBLIC_URL + '/images/play_L.png'} alt="play-picto"/>{item.snippet.title}
</CardTitle>
</Card>
</Col>
);
})}
<Modal role="dialog" isOpen={this.state.modal} toggle={this.toggleModal}>
<ModalHeader className="custom-modal-header" toggle={this.toggleModal}>
<img src={process.env.PUBLIC_URL + './images/logo.png'} alt="La Baule TV logo" className="LBTV-logo"></img>
<span className="ml-2">La Baule</span></ModalHeader>
<ModalBody>
<ReactPlayer className="video-player"
url={'https://www.youtube.com/watch?v=T_IUcX17GXE&t=7s'}
playing= {true}
config={{
youtube: {
playerVars: {
modestbranding: 1,
controls: 1,
rel: 0
}
}}}
/>
</ModalBody>
</Modal>
</Row>
</Box>
</div>
)
}
}
export default Videos;
1 ответ
Чтобы воспроизвести видео, на которое вы нажали, вам нужно получить videoId
конкретного видео и изменить URL-адрес в ReactPlayer
чтобы выглядеть примерно так https://www.youtube.com/watch?v=xxxxxxxxxxx.
Создайте функцию под названием onThumbnailClick
или какое-либо другое имя, которое является функцией, которая должна выполняться при нажатии на миниатюру. Так что вместо <Card className="card-wrapper" onClick={() => {this.toggleModal()}}>
сделать что-то вроде <Card className="card-wrapper" onClick={() => {this.onClickThumbnail(index)}}>
, (У нас есть индекс видео с карты, использованной ранее)
Эта функция должна установить состояние с помощью URL-адреса видео. Мы передаем индекс в функцию. Получить от this.state.videos
, this.state.videos[index]
который будет кликнул видео.
Мы знаем, что videoId этого конкретного видео находится в состоянии видео. this.state.videos[index].snippet.resourceId.videoId
даст вам идентификатор видео. Установите состояние с этим videoId, а затем откройте модальное.
onClickThumbnail = (index) => {
this.setState({
clickedVideoId: this.state.videos[index].snippet.resourceId.videoId
})
this.toggleModal()
}
и измените URL ReactPlayer на
url={`https://www.youtube.com/watch?v=${this.state.clickedVideoId}`}