how to select clicked element in reactjs? - reactjs

I am new to reactjs in this i have defined components and i am passing title to audio cards and by using title i am also defining source of the audio files. and after clicking on that particular component i want to play that particular audio file.
in js we can achieve this using $(this).find();
but in reactjs how to do it can anyone help me
import React from 'react';
import AudioCard from './AudioCard';
import '../css/RecommendedAudios.css';
function RecommandedAudios() {
return (
<div className="recommandedaudios">
<h2>Recommanded</h2>
<div className="recommandedaudios_audios">
<AudioCard title="Arrows to Athens - Alive" />
<AudioCard title="Arrows to Athens - Dust & Gold" />
<AudioCard title="Arrows to Athens - Stars" />
<AudioCard title="Arrows to Athens - Used to be" />
<AudioCard title="Bryan Adams - Here I am" />
<AudioCard title="My Heart Belongs to You" />
<AudioCard title="Ravenscode - My Escape" />
</div>
</div>
);
}
export default RecommandedAudios;
import React from 'react';
import '../css/AudioCard.css';
import PlayArrowIcon from '#material-ui/icons/PlayArrow';
function AudioCard({ title, timestamp }) {
var playsong = () => {
const select = document.querySelector("audio");
select.play();
};
return (
<div onClick={playsong} className="audiocard">
<PlayArrowIcon />
<div className="audiocard_info">
<div className="audiocard_title">
<h5>{title}</h5>
<audio src={require(`../sounds/${title}.mp3`)}></audio>
</div>
</div>
</div>
);
}
export default AudioCard;

document.querySelector("audio") will return the first "audio" tag in the HTML, not the specific one you're looking for
you can use ref:
import React, { useRef } from 'react'
function AudioCard({ title, timestamp }) {
const audioEl = useRef(null);
const playsong = () => audioEl.current.play();
return (
<div onClick={playsong} className="audiocard">
<PlayArrowIcon />
<div className="audiocard_info">
<div className="audiocard_title">
<h5>{title}</h5>
<audio ref={audioEl} src={require(`../sounds/${title}.mp3`)}></audio>
</div>
</div>
</div>
);
}

You can use react-audio-player instead of using query selector and HTML audio tag
you can install it by
npm install --save react-audio-player
and inport the library to your code and use
import ReactAudioPlayer from 'react-audio-player';
const [audio,ReferAudio] = useState()
...........
<div onClick={playsong} className="audiocard">
<PlayArrowIcon />
<div className="audiocard_info">
<div className="audiocard_title">
<h5>{title}</h5>
<ReactAudioPlayer
src={require(`../sounds/${title}.mp3`)}
controls
ref={(e) => { ReferAudio(e) }}
/>
</div>
</div>
</div>
you can access the player by using audio
you can lern more here

Related

I Create a react.js component and it doesn't render

I Create a component and it doesn't render (react js) < --- completely newbie react js user
first i create well structure of a card in list
meetupitems.js
import { Action } from 'history';
import css from './Meetupitems.module.css';
function Meetupitem(props) {
<li className={css.item}>
<div className={css.image}>
<image src={props.image} alt={props.title} />
</div>
<div className={css.content}>
<h3>{props.title}</h3>
<address>{props.address}</address>
<p>{props.description}</p>
</div>
<div className={css.actions}>
<button></button>
</div>
</li>;
}
export default Meetupitem;
then use map() to create card list from "list of data"
Meetuplist.js
import Meetupitem from "./Meetupitems";
import css from "./Meetuplist.module.css";
function Meetuplist(props) {
return (
<ul className={css.list}>
{props.meetups.map((meetup) => (
<Meetupitem
key={meetup.id}
title={meetup.title}
image={meetup.image}
address={meetup.address}
description={meetup.description}
/>
))}
</ul>
);
}
export default Meetuplist;
and when i'm trying to use it
Allmeetup.js
import Meetupitem from "./Meetupitems";
import css from "./Meetuplist.module.css";
function Meetuplist(props) {
return (
<ul className={css.list}>
{props.meetups.map((meetup) => (
<Meetupitem
key={meetup.id}
title={meetup.title}
image={meetup.image}
address={meetup.address}
description={meetup.description}
/>
))}
</ul>
);
}
export default Meetuplist;
the result I saw was a blank page at the index route(where the list should show)
but others route was fine
I can't figure out what's wrong
I think the issue is nothing is being returned from your Meetupitem component. There is no return statement in it.
I believe if you look in console in chrome dev tools, you will be able to see the error messages for it.
Try changing it to as shown below:
import { Action } from 'history';
import css from './Meetupitems.module.css';
function Meetupitem(props) {
return (
<li className={css.item}>
<div className={css.image}>
<image src={props.image} alt={props.title} />
</div>
<div className={css.content}>
<h3>{props.title}</h3>
<address>{props.address}</address>
<p>{props.description}</p>
</div>
<div className={css.actions}>
<button></button>
</div>
</li>;
)
}
export default Meetupitem;

Working with images local files in Gatsby.js

I am trying to render a headshot for each artist displayed on the page. The artist data comes from a Json file, and the images are located in images/artists/headshots. I am using the regular img tag, but for some reason nothing is displaying on the page. Any help any one can give would be greatly appreciated.
import React from 'react'
import PropTypes from 'prop-types'
import { StaticImage } from 'gatsby-plugin-image'
import { useStyles } from './styles'
const ArtistsPage = ({ data }) => {
const classes = useStyles()
return (
<section>
<article className={classes.artistsBackground}>
<div className={classes.heroLayoutContainer}>
<h3 className={classes.title}>MEET THE ARTISTS</h3>
<StaticImage
className={classes.heroImage}
src='../../images/artists/hero-images/hero-image-artists.jpg'
alt='hero-image-artists'
placeholder='blurred'
/>
</div>
</article>
<article className={classes.artistsContainer}>
<div className={classes.flexContainer}>
{data.allArtistsJson.edges
.map(({ node }, idx) => {
const artist = `${node.firstName}+${node.lastName}`
.split('+')
.join(' ')
return (
<div className={classes.flexItem} key={idx}>
<div>
<img
src={`../../images/artists/headshots/${artist} Headshot.jpg`}
alt='artist-headshot'
/>
</div>
<div className={classes.artistCardName}>
{`${node.firstName} ${node.lastName}`.toUpperCase()}
</div>
<div className={classes.artistCardText}>{node.city}</div>
<div className={classes.artistCardText}>
{node.currentTeam}
</div>
</div>
)
})}
</div>
</article>
</section>
)
}
export default ArtistsPage
My image files are set up as:
FirstName LastName Headshots.jpg
I think your issue may comes from the white spaces in the naming. Your code looks good at first sight so try renaming your images with underscore or in camelCase:
<img
src={`../../images/artists/headshots/${artist}_Headshot.jpg`}
alt='artist-headshot'
/>
After much research and the nice people on Gatsby discord I found the answer to be… in a scenario like this I needed to add require().default.
Ex:
<img
src={require(../../images/artists/headshots/${artist} Headshot.jpg).default}
alt='artist-headshot'
/>

Image doesn't display React

I'm building a website by react and my local image doesn't display. I use props to pass the properties from Cards.js to CardItem.js then every properties display except image. I don't know what is a problem with my code :(
Here is Cards.js:
import React from 'react'
import CardItem from './CardItem'
import './Cards.css'
function Cards() {
return (
<div className="cards">
<h1>Check out these EPIC Destinations!</h1>
<div className="cards-container">
<div className="cards-wrapper">
<ul className="cards-items">
<CardItem
src='../assets/images/img-9.jpg'
text='Explore the hidden waterfall deep inside the Amazon Jungle'
label='Adventure'
path='/sevices'
/>
</ul>
</div>
</div>
</div>
)
}
export default Cards
CardItem.js:
import React from 'react'
import { Link } from 'react-router-dom'
function CardItem(props) {
return (
<>
<li className="cards-item">
<Link className="cards-item-link" to={props.path}>
<figure className="cards-item-pic-wrap" data-category={props.label}>
<img src={props.src} alt="Travel Img" className="cards-item-img" />
</figure>
<div className="cards-item-info">
<h5 className="cards-item-text">{props.text}</h5>
</div>
</Link>
</li>
</>
)
}
export default CardItem
we want to import the image first
import img from './assets/images/img-9.jpg';
We named image as img use it in your code.
import React from 'react'
import CardItem from './CardItem'
import './Cards.css'
import img from './assets/images/img-9.jpg';
function Cards() {
return (
<div className="cards">
<h1>Check out these EPIC Destinations!</h1>
<div className="cards-container">
<div className="cards-wrapper">
<ul className="cards-items">
<CardItem
src={img}
text='Explore the hidden waterfall deep inside the Amazon Jungle'
label='Adventure'
path='/sevices'
/>
</ul>
</div>
</div>
</div>
)
}
export default Cards
first import image
import img from '../assets/images/img-9.jpg'
then use it
<CardItem src={img} .../>
I hope this helps you, resources https://create-react-app.dev/docs/using-the-public-folder/:
for Cards.js file:
...
<CardItem
src='/images/img-9.jpg'
text='Explore the hidden waterfall deep inside the Amazon Jungle'
label='Adventure'
path='/services'
/>
And...
for CardItem.js file:
...
<img
className='cards__item__img'
alt='Travel'
src={process.env.PUBLIC_URL + props.src}
/>

Trying to append an API value to a controlled input field with React Hooks

When the component loads, I am making an axios call to a Geolocation API. If the user agrees to let the app get their location, it gets their zipcode. I am then trying to append the zipcode to the zipcode input field, but I can't figure out how to do it. This is my landing page.
import React, { useState, useEffect, useRef } from 'react';
import './App.scss';
import axios from 'axios';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faBars } from '#fortawesome/free-solid-svg-icons';
import LandingPage from './components/landingPage';
function App() {
const[zipcode, setZipcode] = useState();
useEffect(() => {
axios({
"method":"GET",
"url":"https://find-any-ip-address-or-domain-location-world-wide.p.rapidapi.com/iplocation",
"headers":{
"content-type":"application/octet-stream",
"x-rapidapi-host":"find-any-ip-address-or-domain-location-world-wide.p.rapidapi.com",
"x-rapidapi-key":x-rapidapi-key,
"useQueryString":true
},
"params":{
"apikey":apikey
}
})
.then((response)=>{
console.log(response.data.zipCode);
setZipcode(response.data.zipCode);
})
.catch((error)=>{
console.log(error)
});
},[]);
return (
<div className="App" path='/'>
<header className='container'>
<div className='row'>
<div className='col-1'>
<button>
<h1><FontAwesomeIcon icon={faBars} /></h1>
</button>
</div>
<div className='col'>
<h1>MDNight</h1>
</div>
</div>
</header>
<LandingPage zipcode={zipcode} setZipcode={setZipcode} />
<footer className='container'>
<h2>Copyright 2020</h2>
</footer>
</div>
);
}
export default App;
And here is the child component.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function LandingPage(props) {
function handleInputChange(e) {
props.setZipcode(e.target.value);
};
return (
<main className='container'>
<div className='row'>
<div className='col'>
<h1>Welcome to <span>MDNight</span>!</h1>
<h2>The website that makes your date night more convenient.</h2>
<p>Let's assume that you and your "Significant Other" would like to go out for a date night, however, you have to continually switch back and forth between websites looking at showtimes and trying to find a place to eat beforehand. Well, that's where <span>MDNight</span> comes in! We take your location, movie you're interested in seeing, , and show you theaters that are showing your movie, and a list of restaurants nearby. Sound Convenient to you? Enter your info below to get started!</p>
</div>
</div>
<div className='row'>
<div className='col'>
<label htmlFor='zipcodeInput'>Please Enter Your zipcode to get started!</label>
</div>
</div>
<div className='row'>
<div className='col'>
<input name='zipcodeInput' type="text" value={props.zipcode} onChange={handleInputChange} />
</div>
</div>
<div className='row'>
<div className='col'>
<button className='btn btn-primary'>Get Started!</button>
</div>
</div>
</main>
);
}
export default LandingPage;
I've only ever used useState and useEffect, so I don't know if one of the other hooks solves this problem, but if someone could show me how that would be amazing.
I found this answer from someone on a React FB group. I added defaultValue={props.zipcode} to the input and it worked perfectly. I did not know about defaultValue until today.
You do not need zipcode as a dependency of the useEffect hook in the App component. I would suggest having an empty array as your dependency array because you want this hook to run on mount only.

Using fullpagejs in React, how to trigger function on active slide without re-rendering entire page

In my React app I am using fullpage.js to render two slides containing two different components. I want to run a function inside one of these only when it's the active slide. I tried below code, but once the state changes the entire ReactFullpage is re-rendered causing the first slide to be active again so I'm basically stuck in a loop.
My question is, how can I trigger a function inside the <Player /> component to run only if it's the active slide?
import React from "react";
import ReactFullpage from "#fullpage/react-fullpage";
import AlbumInfo from './AlbumInfo';
import Player from './Player';
class Album extends React.Component {
constructor(props){
super(props);
this.state={
playing: false
}
}
_initPlayer = (currentIndex, nextIndex) => {
if(nextIndex.index === 1) {
this.setState({playing:true})
}
}
render() {
return (
<ReactFullpage
licenseKey='xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx'
sectionsColor={["#000000"]}
afterLoad={this._initPlayer}
render={({ state, fullpageApi }) => {
return (
<div id="fullpage-wrapper">
<div className="section">
<AlbumInfo />
</div>
<div className="section">
<Player playing={this.state.playing} />
</div>
</div>
);
}}
/>
);
}
}
export default Album;
From docs:
just add the class 'active' to the section and slide you want to load first.
adding conditionally (f.e. using getActiveSection()) 'active' class name should resolve rerendering problem.
The same method/value can be used for setting playing prop.
Probably (I don't know/didn't used fullpage.js) you can also use callbacks (without state management and unnecessary render), f.e. afterSlideLoad
Update
The issue has been fixed on https://github.com/alvarotrigo/react-fullpage/issues/118.
Version 0.1.15 will have it fixed
You should be using fullPage.js callbacks afterLoad or onLeave as can be seen in the codesandbox provided on the react-fullpage docs:
https://codesandbox.io/s/m34yq5q0qx
/* eslint-disable import/no-extraneous-dependencies */
import React from "react";
import ReactDOM from "react-dom";
import "fullpage.js/vendors/scrolloverflow"; // Optional. When using scrollOverflow:true
import ReactFullpage from "#fullpage/react-fullpage";
import "./styles.css";
class FullpageWrapper extends React.Component {
onLeave(origin, destination, direction) {
console.log("Leaving section " + origin.index);
}
afterLoad(origin, destination, direction) {
console.log("After load: " + destination.index);
}
render() {
return (
<ReactFullpage
anchors={["firstPage", "secondPage", "thirdPage"]}
sectionsColor={["#282c34", "#ff5f45", "#0798ec"]}
scrollOverflow={true}
onLeave={this.onLeave.bind(this)}
afterLoad={this.afterLoad.bind(this)}
render={({ state, fullpageApi }) => {
return (
<div id="fullpage-wrapper">
<div className="section section1">
<h3>Section 1</h3>
<button onClick={() => fullpageApi.moveSectionDown()}>
Move down
</button>
</div>
<div className="section">
<div className="slide">
<h3>Slide 2.1</h3>
</div>
<div className="slide">
<h3>Slide 2.2</h3>
</div>
<div className="slide">
<h3>Slide 2.3</h3>
</div>
</div>
<div className="section">
<h3>Section 3</h3>
</div>
</div>
);
}}
/>
);
}
}
ReactDOM.render(<FullpageWrapper />, document.getElementById("react-root"));
export default FullpageWrapper;

Resources