Display images dynamically using map() in react not working - reactjs

I want to display images in the sports array using map(). but not working
<div className="row">
{this.state.sports.map(function(sport, index){
return (
<div className="col-md-3" key={index}>
<h3 className="text-center">{this.state.sports.name}</h3>
<img src={ require('./../assets/images/'+ {this.state.sports.name} +'.jpg') } width="300px" height="180px" />
<button className="btn btn-info btn-sm" type="submit" onClick={this.join_in_sport} >JOIN</button>
</div>
)
}.bind(this))}
</div>

The problem seems to lie in how you are building the pathname for your image. Same for your <h3> tag.
src={ require('./../assets/images/'+ {this.state.sports.name} +'.jpg') }
If this.state.sports is an array, and not an object, then it can't possibly have a name key. I think you meant to print the current objects name for each iteration in your map().
So try:
<h3 className="text-center">{this.state.sports.name}</h3>
<img src={ require('./../assets/images/'+ {sport.name} +'.jpg') } width="300px" height="180px" />
This is assuming your array looks something like:
[
{name: "foo"},
{name: "bar"}
]

I have encountered the same problem,
the image folder in src doesn't work.
I moved the image folder to public and it works fine.
function App() {
const moviesData = [
name: "Terminator: Dark Fate",
img: "./badboy3.jpg", //image in public folder
},
];
const movieList = moviesData.map((movie, i) => {
return <Movie key={i} movieName={movie.name} movieImg={movie.img} />;
});
return (
<div>
{movieList}
</div>
);
}
export default App;

I was following the React beginners tutorial tried to call images dynamically by importing them as variables but this simply didn't work when trying to call them in another file (App.js) using the .map() function. Code below:
import katieImg from "../images/Katie.png";
import starImg from "../images/Katie.png";
export default [
{
img: { katieImg },
star: { starImg },
rating: "5.0",
reviewCount: 6,
location: "USA",
title: "Life Lessons with Katie Zaferes",
price: 136,
},
];
So instead I had to get rid of the dynamically imported variables and put the images folder in the public folder. This worked. Code below:
export default [
{
img: "../images/Katie.png",
star: "../images/Star.png",
rating: "5.0",
reviewCount: 6,
location: "USA",
title: "Life Lessons with Katie Zaferes",
price: 136,
},
];

Related

Icons not showing in react when using material-icons using cdn instead showing their text

I am using react with material-icons without npm as I am using cdn link .
Now I have saved their tags in a external file and calling them in a component but instead of showing icons they are showing their text.
This is my array that I am calling
export const LeftbarTop = [
{
id: 1,
name: "Apps",
icon:<span className="material-icons-outlined">
widgets
</span>,
},
{
id: 2,
name: "Help",
icon: <span className="material-icons-outlined">
help_outline
</span>,
},
];
This is my component through which I am calling this file/array
import {LeftbarTop} from '../../data/sidebar_activity'
function Leftbar(){
const arr = [...LeftbarTop];
return (<>
<div className="leftbar">
<div className="leftbar-topbar">
{arr.map(ele => <LeftList arr={ele}/>)}
</div>
<div className="leftbar-bottombar"></div>
</div>
</>)
}
this is my LeftList component that simply shows that data
function LeftList ({arr}){
return (
<div >
<div >{arr.icon}</div>
{arr.name && <label>{arr.name}</label>}
</div>
)
}
this whole shows icons as
widgets Apps
help_outline Help

Adding an image and an anchor tag to an element within an array using props in React

While creating cards and using props in React.js I need to add an anchor tag(website:) and an image (image:) within a few elements in an array but am unable to figure out how. Of course, as seen below simply just adding an anchor tag etc does not work. Any help would be appreciated.
const projects = [
{
id: 1,
image: <img src="https://picture.jpg" alt="Coaching Website">
name: "Personal Coaching Website",
meaning:"A comprehensive website for a personal health and wellness coach"
website:
},
Rather than defining elements in an array, use the values, and map into the properties of the element.
const projects = [
{
id: 1,
image: "https://picture.jpg",
name: "Personal Coaching Website",
meaning: "A comprehensive website for a personal health and wellness coach",
website: "https://www.samplewebsite.com"
}
];
export default function App() {
return (
<div>
{projects.map(project => {
return (
<div>
<img src={project.image} />
<a href={project.website} />
</div>
);
})}
</div>
);
}

Basic usage of keys - Extract single item prop from data list

In React I have an array of projects (only 2 in this example). Each project has:
key
name
info
I would like to be able to render, for example, only one project name. Everything I have tried gives me the whole list. I am confused on the format I need to use to:
Set up my ID
Tell React what specific ID I want to render
I have tried creating different formats (Try number 1 & 2) using .map
function ProjectList() {
const projects = [
{
id: 0,
name: "Shop",
date: "2019",
info: "info of 1",
},
{
id: 1,
name: "Hotel",
date: "2019",
info: "info of 2",
},
]
const findProjectInfo = projects.map (project =>(
<div key={1}>
<h2 key={project.ID}>
{project.info}
</h2>
</div>
))
return (
<div>
<div className='TRY NUMBER ONE' key={1}>
{projects.map (project=> (
<div key={project.ID}>
<div> {project.name}</div>
<div> {project.info}</div>
</div>
))}
</div>
<div className='TRY NUMBER TWO' key={1}>
{findProjectInfo}
</div>
</div>
)
}
export default ProjectList
Everything I tried gives me the two items of my list and not only the 1st one as I would want.
Try something like that:
const projects = [
{
id: 0,
name: "Shop",
date: "2019",
info: "info of 1",
},
{
id: 1,
name: "Hotel",
date: "2019",
info: "info of 2",
},
];
function ProjectList() {
const [selectedProject,setSelectedProject] = React.useState(0);
return (
<React.Fragment>
<div>Select Project</div>
<button onClick={()=>setSelectedProject(0)}>Project 1</button>
<button onClick={()=>setSelectedProject(1)}>Project 2</button>
<br/><br/>
<div><b>Project name: </b>{projects[selectedProject].name}</div>
<div><b>Project date: </b>{projects[selectedProject].date}</div>
<div><b>Project info: </b>{projects[selectedProject].info}</div>
</React.Fragment>
);
}
ReactDOM.render(<ProjectList/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
.map will always return you an array with the same size as the original. What you want to do is find a specific element, like this:
const project1 = findProjectInfo.find(project => project.id === 1);
This will return a single object instead of an array, which you can then render:
<div>
<div>{project.name}</div>
<div>{project.info}</div>
</div>
More info on Array.prototype.find() here.
The key prop is not to be used for anything related to this. It is a special prop that helps React know when components change, and only usually needed when you want to render arrays (like when you use .map), or in a few more advanced cases.
You are simply iterating through your array, that is why you are getting every element from array as result.
You need to first filter your array using provided ID and then you can iterate using map,
{projects
.filter(projects => projects.id === providedID) //providedID can be stored in state
.map(project => (
<div key={project.id}>
<h2 key={project.id}>{project.info}</h2>
</div>
))
}
Demo
Note: Don't use key like this,
<div className='TRY NUMBER ONE' key={1}>
Also make sure you don't repeat the key for multiple elements.
Update
Changing state and getting project details based on selected project ID.
Demo1

React returns image src as object

I have a variable defined like this:
const team = [
{
name: "Foo",
bio: "FooBar",
image: { foo }
},
{
name: "Bar",
bio: "FooBar",
image: { bar }
},
];
Where the images are imported like this:
import foo from "../assets/foo.jpg";
import bar from "../assets/bar.jpg";
These are then passed to a component to be rendered, with:
<TeamRow team={team} />
The TeamRow component looks like this:
const TeamRow = props => {
const items = props.team.map((item, index) => {
return (
<div className="col-10 col-sm-4 col-md-1 mx-auto text-center">
<div className="row">
<div className="col-12 teamMemberImage">
<img className="img-fluid" src={item.image} />
</div>
</div>
<div className="row">
<div className="col-12">{item.name}</div>
</div>
<div className="row">
<div className="col-12">{item.bio}</div>
</div>
</div>
);
});
return <div className="row">{items}</div>;
};
export default TeamRow;
The images fail to render. When I look at them in the dev tools, they have src="Object object". The class that calls TeamRow, is the class in which team is defined. After defining it, calling console.log(foo returns the url pointing to the image, as expected. Somehow, in being passed to the second component, the expected behaviour ceases.
Strangely, earlier, I was using the react logo as a placeholder. So:
import logo from "../assets/logo.svg";, and this worked, but only if I rendered it as src={item.image.logo}.
{ foo } is shorthand for { foo: foo }, and { bar } is shorthand for { bar: bar }.
Instead of putting the image url in an object with a key that will be different for every image, you can set it as the image property directly.
const team = [
{
name: "Foo",
bio: "FooBar",
image: foo
},
{
name: "Bar",
bio: "FooBar",
image: bar
},
];
team[0].image is an object on the form {"foo":"yourUrl"} because you've wrapped foo in brackets, which uses the object shorthand syntax to create a property named foo with the value in variable foo. Remove the brackets around foo and bar
You don't need to put your image files alias names inside the {foo}, you can just write image: foo otherwise it will return as [object object].
In my case, I was struggling for the last four hours. but, it was a Next JS project so I need to put the image properties in an image component.
<Image src={props.img} /> instead of <img>

Reusing markup in reactJS and best practice

I am learning react and I am attempting to reuse code (I'm told that's one of the great things about react). I currently have the following markup with the data sets imported like so. I have attempted to loop through the data set using .map but its proving to be difficult. Is there a best practice (slightly discussion focued rather than just answerable as stack overflow outlines, but I'm attempting to learn) when it comes to looping through data. Thanks
JS
import {recommendedActivities3} from '../../data/mocks'
import {recommendedActivities4} from '../../data/mocks'
<Link className={`PageCell recommended`} to={`/places/top-activities/${recommendedActivities3.id}`}>
<div className={`restaurantCard-main recommended`}>
<span className="host-recommendation-text">Host recommended</span>
<div className={`restaurantCard recommended`}>
<img className={`photo activity`} src={recommendedActivities3.image_url} size="small" alt="activities" />
<div className={`restaurantCard-right`}>
<div className="name">{recommendedActivities3.name}</div>
<div className="description"><p>{recommendedActivities3.description}</p></div>
</div>
</div>
</div>
</Link>
<Link className={`PageCell recommended`} to={`/places/top-activities/${recommendedActivities4.id}`}>
<div className={`restaurantCard-main recommended`}>
<span className="host-recommendation-text">Host recommended</span>
<div className={`restaurantCard recommended`}>
<img className={`photo activity`} src={recommendedActivities4.image_url} size="small" alt="activities" />
<div className={`restaurantCard-right`}>
<div className="name">{recommendedActivities4.name}</div>
<div className="description"><p>{recommendedActivities4.description}</p></div>
{/*<CellContent recommendedActivities={recommendedActivities} recHeight={recHeight} normalHeight={normalHeight} />*/}
</div>
</div>
</div>
</Link>
Data
Below I have provided the structure of my data for reference. Not sure if it is necessary.
export const recommendedActivities4 = {
description: 'One of the best spots in SFs Famous: North Beach. Grab a coffee and just people watch for hours!',
id: 'tartine-bakery-and-cafe-san-francisco',
name: 'Tartine Bakery & Cafe',
image_url: 'https://s3-media3.fl.yelpcdn.com/bphoto/vTLu8G86IqIazm7BRqIH4g/o.jpg',
is_closed: false,
url:
'https://www.yelp.com/biz/nopa-san-francisco?adjust_creative=oj0judbJDVIHIVps_GJrXQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=oj0judbJDVIHIVps_GJrXQ',
review_count: 4636,
categories: [
{
alias: 'newamerican',
title: 'American (New)',
},
{
alias: 'modern_european',
title: 'Modern European',
},
],
rating: 4,
coordinates: {
latitude: 37.774905,
longitude: -122.437506,
},
transactions: ['restaurant_reservation'],
price: '$$$',
location: {
address1: '560 Divisadero St',
address2: null,
address3: '',
city: 'San Francisco',
zip_code: '94117',
country: 'US',
state: 'CA',
display_address: ['560 Divisadero St', 'San Francisco, CA 94117'],
},
phone: '+14158648643',
display_phone: '(415) 864-8643',
distance: 255.549722789804,
}
So lets say you have some small component that you want to use to just render one recommended activity link. it would look something like this
const RecommendedActivity = ({activity}) => {
return (
<Link className="PageCell recommended" to={`/places/top-activities/${activity.id}`}>
<div className="restaurantCard-main recommended">
<span className="host-recommendation-text">Host recommended</span>
<div className="restaurantCard recommended">
<img className="photo activity" src={activity.image_url} size="small" alt="activities" />
<div className="restaurantCard-right">
<div className="name">{activity.name}</div>
<div className="description"><p>{activity.description}</p></div>
</div>
</div>
</div>
</Link>
)
}
this makes it a reusable component. So then the way you would use it is like so:
first lets make an array of recommended activities to work with const seed = [recommendedActivities3, recommendedActivities4]
now in the render method you would just call the particular component for each element in the array
{ seed.map( (activity, idx) => <RecommendedActivity activity={activity} key={idx}/>)}

Resources