Render different html depending on index of object in react - javascript

In my meteor project I have a collection called auctions. Using react I wish to render 3 columns of this auctions with unlimited number of rows. To accomplish this I thought it would be possible to send the index of the object but I have no idea how to do this. Another problem is that it shows an error with the html code since I'm not closing the 'div' tag.
This is my App.js:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { withTracker } from 'meteor/react-meteor-data';
import { Auctions } from '../api/auctions.js';
import Auction from './Auction.js';
//App component - represents the whole app
class App extends Component {
renderAuctions() {
return this.props.auctions.map((auction, index) => (
<Auction key={auction._id} auction={auction} index={index} />
));
}
render() {
return (
<div className="container section">
<div className="row">
{this.renderAuctions()}
</div>
</div>
);
}
}
export default withTracker(() => {
return {
auctions: Auctions.find({}).fetch(),
};
})(App);
And my Auction.js:
import React, { Component } from 'react';
//Task component - resepresnts a single todo item
export default class Auction extends Component {
render() {
if(index % 3 === 0) {
return (
</div> /* Shows an erros here because of closing tag*/
<div className="row">
<div className="col s4 ">
<div className="card">
<div className="card-image">
<img src="images/logo.png" />
</div>
<div className="card-content">
<span className="card-title">
{this.props.auction.auctionName}
</span>
<p>
I am a very simple card. I am good at containing small bits of information.
I am convenient because I require little markup to use effectively.
</p>
</div>
<div className="card-action">
This is a link
</div>
</div>
</div>
);
} else {
<div className="col s4">
<h1>Brincoooo</h1>
<div className="card">
<div className="card-image">
<img src="images/logo.png" />
</div>
<div className="card-content">
<span className="card-title">
{this.props.auction.auctionName}
</span>
<p>
I am a very simple card. I am good at containing small bits of information.
I am convenient because I require little markup to use effectively.
</p>
</div>
<div className="card-action">
This is a link
</div>
</div>
</div>
}
}
}

Any time you return HTML from a render function it needs to be self contained and have balanced tags. That's the way React works, and why it's giving you an error.
Instead of trying to group 3 auctions at a time, you could think of using flexbox instead. With flexbox you simply render all of your auctions, and it looks after the wrapping automatically for you. Users with wider screens will see more than 3 columns, and users on mobile will see probably one when in portrait mode.
If you want to learn about flexbox, there is a cute tutorial here: https://flexboxfroggy.com/ There are plenty of tutorials around if you don't like that one, such as this: https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties
I'll let you do the work from here

Related

How to manipulate/modify external UI component library in react?

I'm working on an app that uses an open source calendar library that renders the day as spans. I wish to change certain days to another button component library.
Example snippet of the external library usage
import Calendar, { CalendarView } from 'calendar' // import component
import '../styles/index.css'; // import styles
const CalendarComponent: FC<CalendarComponentType> = ({
{...props}
}) => {
return (
<>
<Calendar
onEventClick={onEventClick}
onNewEventClick={onNewEventClick}
events={[]}
initialDate={new Date().toISOString()}
hourHeight={60}
initialView={CalendarView.WEEK}
disabledViews={[CalendarView.DAY]}
onSelectView={onSelectView}
selectedView={selectedView}
onPageChange={onPageChange}
timeFormat={'24'}
weekDayStart={'Monday'}
calendarIDsHidden={['work']}
language={'en'}
/>
</>
);
}
export default CalendarComponent;
it renders a deeply nested HTML component
<div class="CalendarContainer">
<div class="CalendarNavigation">
... content
</div>
<div class="CalendarBody">
<div class="CalendarTimeTable">
<div id="Calendar_day__2022-08-01" class="DayViewOneDay">
<span class="Calendar_text__day">01</span>
... content
</div>
<div id="Calendar_day__2022-08-02" class="DayViewOneDay">
<span class="Calendar_text__day">02</span>
... content
</div>
<div id="Calendar_day__2022-08-03" class="DayViewOneDay">
<span class="Calendar_text__day">03</span>
... content
</div>
<div id="Calendar_day__2022-08-04" class="DayViewOneDay">
<span class="Calendar_text__day">04</span>
... content
</div>
<div id="Calendar_day__2022-08-05" class="DayViewOneDay">
<span class="Calendar_text__day">05</span>
... content
</div>
</div>
</div>
</div>
For example, I want to modify certain days from <span> to button component from another component library so it becomes
<div id="Calendar_day__2022-08-02" class="DayViewOneDay">
<CustomButton>
... content
</CustomButton>
... content
</div>
Is there any way to do this without modifying the source library?

how to get the clicked element when clicked in ReactJS when using map?

I am mapping 'MemeCard.js' elements inside the 'Home.js' using ReactJs 'map' function.
In Home.js element mapping is done like this
memes = ["url1","url2","url3","url4"];
return (
<div className="container my-3">
<div className="row">
{memes.map((meme, index) => {
return (
<div className="col-xl-4 my-5">
<MemeCard imgurl={meme} index={index} />
</div>
);
})}
</div>
</div>
);
My MemeCard element is
import React from 'react';
import MemeCSS from './MemeCard.module.css';
import whiteHeart from '../images/bordered_heart.png';
import blueHeart from '../images/blue_heart.png';
import Share from '../images/share.png';
export default function MemeCard(props) {
function likeBtnClicked(index){
document.getElementById("heartIMG").setAttribute("src",blueHeart);
console.log(index);
}
return (
<div className={MemeCSS.box}>
<img className={MemeCSS.memeImg} src={props.imgurl} alt="meme" />
<div className={MemeCSS.divbutton}>
<img className={MemeCSS.shareImg} src={Share} alt="share" />
<img
id="heartIMG"
className={MemeCSS.likeImg}
onClick={()=>{likeBtnClicked(props.index);}}
src={whiteHeart}
alt="like"
/>
</div>
</div>
);
}
What I want to do is :
Change the 'likeImage' from 'whiteHeart' image to 'blueHeart' (both of which I have imported), when clicked on the 'whiteHeart' image using the 'onClick'.
But, no matter which 'MemeCard's 'whiteHeart' image I click, the code is changing only the image of the first item to 'blueHeart'. Because it is getting only the "document.getElementById("heartIMG")" of the first item everytime.
But the index is printing the index of the correct item(which is clicked).
Can someone tell me how to solve this problem?
Yous should add a dyanmic function which works for each component indvidually.:
// MemeCard.js
import React from 'react';
import MemeCSS from './MemeCard.module.css';
import whiteHeart from '../images/bordered_heart.png';
import blueHeart from '../images/blue_heart.png';
import Share from '../images/share.png';
export default function MemeCard(props) {
function likeBtnClicked(event){
const element = event.currentTarget;
element.setAttribute("src",blueHeart);
}
return (
<div className={MemeCSS.box}>
<img className={MemeCSS.memeImg} src={props.imgurl} alt="meme" />
<div className={MemeCSS.divbutton}>
<img className={MemeCSS.shareImg} src={Share} alt="share" />
<img
id="heartIMG"
className={MemeCSS.likeImg}
onClick={likeBtnClicked}
src={whiteHeart}
alt="like"
/>
</div>
</div>
);
Now all components has there own function.
This will help you ...
https://upmostly.com/tutorials/react-onclick-event-handling-with-examples
or you can use
React JS onClick event handler

ReactJS Props Undefined

I am learning how to use props. After taking research in either my mother language or english, I couldn't end up with a proper answer for my issue.
Please tell me why this threw errors. This is the App.js file (default)
import React from 'react';
import './App.css';
import Product7 from './componentep7/Product7';
function App() {
return (
<div>
<nav className="navbar navbar-inverse">
<div className="container-fluid">
<a className="navbar-brand" >Title</a>
</div>
</nav>
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<Product7 name="valiant"/>
</div>
</div>
</div>
</div>
)
}
export default App;
and this is the component file (Product7.js)
everything is fine except it returned an error at {this.props.name}
import React from 'react';
function Product7() {
return (
<div>
<div className="col-xs-5 col-sm-5 col-md-5 col-lg-5">
<a className="thumbnail">
<img src="https://yuzu-emu.org/images/game/boxart/hollow-knight.png" alt="5tr"/>
</a>
<div className="caption">
<h4>{this.props.name}</h4>
<a className="btn btn-primary">Click to enter</a>
</div>
</div>
</div>
)
}
export default Product7;
Thank you for helping me out.
Props are passed as an argument to function components. You can’t reference this.props. Access it from the props argument:
function Product7 (props) {
return (
<h4>{props.name}</h4>
)
}
don't use this in functional components, <h4>{props.name}</h4>
If you want to use the props in the component, you must define it as a parameter:
function Product7(props) {
...
You should pass props as an argument in your component.
function Product7(props){
...
}
You cant use this in functional component.
Please go through this link.
import React from 'react';
function Product7({name}) {
return (
<div>
<div className="col-xs-5 col-sm-5 col-md-5 col-lg-5">
<a className="thumbnail">
<img src="https://yuzu-emu.org/images/game/boxart/hollow-knight.png" alt="5tr"/>
</a>
<div className="caption">
<h4>{name}</h4>
<a className="btn btn-primary">Click to enter</a>
</div>
</div>
</div>
)
}
export default Product7;
[1]: https://reactjs.org/docs/components-and-props.html
When you are passing props in functional components you have to pass props as an argument for the function.
Another thing is, no need to use this keyword in functional components.
function Product7 (props) {
return (
.
.
.
<h4>{props.name}</h4>
)
}
Note: It is a good habit to practice ECMA Script 6 arrow functions when using functional components, as below.
const Product7 = (props) => {
return (
.
.
.
<h4>{props.name}</h4>
)
}
Looks like you forgot using props within the paranthesis.
function Product7 (props) {
...
...
}
Oh, and make sure not to use this.props as you are using a function based component (only class based components need using this.props)
catch the data by adding props in your function and call it without using this because you are using functional component. i suggest to learn the class component first before jumping functional component

Materialize Css Parallex is not a function

I am trying to use the parallax within a react component. I have gotten this to work in the past. This is a MeteorJs project as well
I get a console error:
$(...).parallax is not a function
My component:
import React from 'react';
import $ from 'jquery';
export default class Index extends React.Component{
render(){
$(document).ready(function(){
$('.parallax').parallax();
});
return(
<div className="container">
<div className="parallax-container">
<div className="parallax"><img src="images/parallax1.jpg"/></div>
</div>
<div className="section white">
<div className="row container">
<h2 className="header">Parallax</h2>
<p className="grey-text text-darken-3 lighten-3">Parallax is an effect where the background
content or image in this case, is moved at a different speed than the foreground content while
scrolling.</p>
</div>
</div>
<div className="parallax-container">
<div className="parallax"><img src="images/parallax2.jpg"/></div>
</div>
</div>
)
}
}
My client main.js file:
import '../imports/startup/client/routes';
import '../node_modules/materialize-css/dist/js/materialize.min';
import '../node_modules/materialize-css/js/parallax';
The error message is telling you that .parallax() isn't a function in this line of code:
``
$('.parallax').parallax();
```
Which means that $('.parallax') is returning an object (usually a html element). It is not surprising that .parallax() is not a function, because it's just a html element.
Looking at the documentation, I think you are missing this initialisation code:
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.parallax');
var instances = M.Parallax.init(elems, options); });

Fluxible and Navlink routing error

I m actually developping an application using fluxible and I m facing a problem using route parameters.
Actually, I m having this render function :
render() {
return (
<div className="card small hoverable">
<div className="card-image">
<img src="http://www.gizmobolt.com/wp-content/uploads/2014/11/14-77.jpg"/>
<span className="card-title">{this.props.title}</span>
</div>
<div className="card-content">
<p>I am a very simple card. I am good at containing small bits of information.
I am convenient because I require little markup to use effectively.</p>
</div>
<div className="card-action">
<NavLink routeName="ProjectDetail" navParams={{id: this.props.key}}>Manage</NavLink>
</div>
</div>
);
}
And this route in my ./conf/routes.js :
ProjectDetail: {
path: '/project/:id/details',
method: 'get',
page: 'ProjectDetail',
title: 'Project detail',
handler: require('../components/ProjectDetail'),
notInMenu:true
}
And here's the error that I get :
/soft/blog/node_modules/fluxible-router/lib/createNavLinkComponent.js:94
throw new Error('NavLink created without href or unresolvable
^
Error: NavLink created without href or unresolvable routeName 'ProjectDetail'
It happens only when I try to use parametered routes in routes.js.
I dont have any idea of making it differently :-/
according to https://github.com/facebook/react/issues/2429 you cannot reference this.key or this.props.key from a component.
The recommendation in this comment is to
I would suggest renaming or duplicating the prop [sic key] name as a possible fix if you really need to access it.
so change your code to something like
render() {
return (
<div className="card small hoverable">
<div className="card-image">
<img src="http://www.gizmobolt.com/wp-content/uploads/2014/11/14-77.jpg"/>
<span className="card-title">{this.props.title}</span>
</div>
<div className="card-content">
<p>I am a very simple card. I am good at containing small bits of information.
I am convenient because I require little markup to use effectively.</p>
</div>
<div className="card-action">
<NavLink routeName="ProjectDetail" navParams={{id: this.props.id}}>Manage</NavLink>
</div>
</div>
);
}
and in the parent rendering component, do:
render() {
{this.states.cards.map(function eachCard(card) {
return <CardItem key={card.id} id={card.id} />;
});
}
It looks like you have the casing wrong: ProjectDetail vs projectDetail. Make sure you are being consistent.

Categories