Passing data between child components in React - javascript

My goal is to use an onClick function in one of my components, and pass that data to another component (end goal is that in the other component called Playlist, it updates an array with the id of the clicked item).
I am just not sure how to pass the information between child components
My main component (app.jsx) looks like this
const mainCards = Data.map(card => {
return(
<MainCard
key={card.id}
id={card.id}
image={card.url}
title={card.title}
playbutton={card.playbutton}
addbutton={card.addbutton}
/>
)
})
const sideCards = SideData.map(card => {
return(
<SideCard
image={card.sideurl}
key={card.id}
title={card.sidetitle}
playbutton={card.playbutton}
addbutton={card.addbutton}
/>
)
})
return (
<div className="App">
<Navbar />
<Header />
<Playlist />
<CardContainer />
<div className="maincards">
{mainCards}
</div>
<div className="sidecards">
{sideCards}
</div>
</div>
)
}
export default App
The component where I am using onClick (MainCard.jsx)
const handleAdd = (id) => {
console.log(id)
}
return(
<div className="mainCardObject">
<div className="cardObj">
<img src={props.image} className ="mainCardImage"/>
<img src={props.playbutton} className="playbutton"/>
<img src={props.addbutton} onClick={() => handleAdd(props.id)} className="addbutton" />
</div>
</div>
)
}
export default MainCard
and the component I wish to pass information to (nothing inside, as I dont know where to start)
return(
<div className="playlistContainer">
<ul>
<li></li>
</ul>
</div>
)
}
export default Playlist```

My suggestion is that you manage 'ids array' state globally creating a context, using the hook useContext(). Here a link with a simple explanation. I hope it helps!
https://www.w3schools.com/react/react_usecontext.asp

Related

how to create the input div on clicking the reply button of a comment below that particular comment using react

I want on clicking the reply button the div to write the reply to come
I tried to create a seperate component for reply textarea but as I am a beginner in react I am not able to get an idea how to do it.
Comment.js
import Userdata from "./data.json";
import Score from "./Score";
import Person from "./person";
import Reply from "./Reply";
const Comment = () => {
return (<div className="sample">{
Userdata.comments.map((comment, index) => {
return (
<div key={comment.id}>
<div className="comment">
<Score score={comment.score} />
<div>
<Person user={comment.user} />
<span className="time">{comment.createdAt}</span>
<Reply index={index} />
<p>{comment.content}</p>
</div>
</div>
{comment.replies.map((reply) => {
return (
<div key={reply.id}>
<div className="comment reply">
<Score score={reply.score} />
<div>
<Person user={reply.user} />
<span>{reply.createdAt}</span>
<Reply />
<p>{reply.content}</p>
</div>
</div>
</div>
);
})}
</div>
);
})
}
</div>
);
}
export default Comment;
Reply Component
const Reply = (props) => {
const handleClick = () => {
console.log(`reply of ${props.index}`)
}
return (
<div onClick= {handleClick} className="btn-reply">
<img className="reply-icon" src="images/icon-reply.svg" alt="reply" />
<span>Reply</span>
</div>
);
}
export default Reply;

How can I send and Receive props in this scenario when component being used like this {Compmonent} and not <Component/>

I'm new to react. I want to receive props from NavItemsLayout but I don't know how
const NavItemsLayout = (props)=>{
return(
<div className="nav-items">
Hellow World
</div>
)
}
const Navbar = ()=>{
return(
<div className="navbar">
<AppLayout
NavLayoutComponent={NavItemsLayout} // How to receive props from NavItemsLayout
/>
</div>
)
}
you can simply use arrow function to do it
sth like this :
<div className="navbar">
<AppLayout
NavLayoutComponent={(props)=> <NavItemsLayout {...props} foo={'bar'} />}
/>
</div>
or use react without jsx
like this :
<div className="navbar">
<AppLayout
NavLayoutComponent={(props)=> React.createElement(NavItemsLayout , {...props,foo: 'bar'}, null)}
/>
</div>

extends/inherit parent component in function

export default function PageTemplate() {
return (
<div className="layout">
<LeftMenu />
<div className="content">
<TopMenu />
<div id="other-contents">
// Contents goes here
</div>
</div>
</div>
);
}
export default function Index() {
return (
<div className="layout">
<LeftMenu />
<div className="content">
<TopMenu />
<div id="other-contents">
<h2>I am Index Page<h2/>
</div>
</div>
</div>
);
}
As you can see most of my contents goes in #other-contents, I will be repeating PageTemplate for every page, I wondering if there is way to just re-use PageTemplate. Instead of repeating code, I would just do something like extends/inherit/whatever possible and reduce the code in Index
I believe this is easier achieved with Class Based Component. But I am wondering if there could function based solution
React prefers Composition over Inheritance. Use the children prop all react components have.
export default function PageTemplate({ children }) {
return (
<div className="layout">
<LeftMenu />
<div className="content">
<TopMenu />
<div id="other-contents">
{children}
</div>
</div>
</div>
);
}
Usage:
<PageTemplate>
// <-- render any content you want here
</PageTemplate>

React; Why does my array.map method render only one element from an array?

I am trying to render a component multiple times based on an array passed on from the parent component. But the child component gets whole array as property so does not render correctly. Can I get any tips on that?
App.js
function App() {
const [businesses, setBusinesses] = useState([]);
function searchYelp(term, location) {
Yelp.search(term, location)
.then((businessesList) => {
setBusinesses([businessesList]); // this should be updated to setBusinesses(businessesList)
})
.then(console.log(businesses));
}
console.log(businesses);
return (
<div>
<Hero>
<SearchBar searchYelp={searchYelp} />
</Hero>
<Layout>
<BusinessList businesses={businesses} />
</Layout>
</div>
);
}
BusinessList.js
const BusinessList = ({ businesses }) => {
return (
<div>
<h2 className="business-list__header">İşletmeler</h2>
<div className="business-list">
{businesses.map((business) => {
return <Business business={business} key={business.id} />;
})}
</div>
</div>
);
};
Business.js
const Business = ({ business }) => {
return (
<div className="business">
<div className="business__image-container">
<img src={business.imageSrc} alt="İşletme Görseli" />
</div>
<div className="business__information">
<h2 className="business__header">{business.name}</h2>
<div className="business__address">
<p className="business__address-text">{business.address}</p>
<p className="business__address-text">{business.city}</p>
</div>
<div className="business__reviews">
<h3 className="business__reviews-header">{business.category}</h3>
<h3 className="business__rating">{business.rating}</h3>
</div>
</div>
</div>
);
};
Any tips would be greatly appreciated.
You can see the values components get below.
Child Component
Extended Parent Component

How to make images fit the page in React/Bootstrap?

I am using a function that maps every item in the props array to creating an image tag. I am trying to make every 3 images have a row div around them using bootstrap so they will fit the page correctly, but I cannot figure out how to do it. Any help would be appreciated. Here is the code:
import React, { Component } from 'react';
import "./Skills.css";
export default class Skills extends Component {
static defaultProps = {
images: [
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/61/HTML5_logo_and_wordmark.svg/1200px-HTML5_logo_and_wordmark.svg.png",
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/CSS3_logo_and_wordmark.svg/1200px-CSS3_logo_and_wordmark.svg.png",
"https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png",
"https://p7.hiclipart.com/preview/306/37/167/node-js-javascript-web-application-express-js-computer-software-others.jpg",
"https://bs-uploads.toptal.io/blackfish-uploads/skill_page/content/logo_file/logo/5982/express_js-161052138fa79136c0474521906b55e2.png",
"https://webassets.mongodb.com/_com_assets/cms/mongodb_logo1-76twgcu2dm.png",
"https://www.pngfind.com/pngs/m/430-4309307_react-js-transparent-logo-hd-png-download.png",
"https://botw-pd.s3.amazonaws.com/styles/logo-thumbnail/s3/012015/bootstrap.png?itok=GTbtFeUj",
"https://sass-lang.com/assets/img/styleguide/color-1c4aab2b.png"
]
}
photo() {
return (
<div >
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</div>
);
}
render() {
return (
<div id="skills-background" className="mt-5">
<div id="skills-heading" className="text-center">Skills I've Learned:</div>
<div className="container">
<div className="row">
{this.photo()}
</div>
</div>
</div>
)
}
}
CodeSandbox
I think, I found the issue,
<div> <-----This div is the issue
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</div>
You have wrapped your col-md-4 with a div, and div has display: block style, so you are getting every image on separate row. Simply replace div with Fragments,
<> <-----Make it Fragment
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</>

Categories