Reactjs map function does not render the component - reactjs

This is the error I am trying to render the createCardHotels function;however, whenever I run it, nothing shows up. Any help will be appreciated.
I used map function to loop through the data and whenever I run it I can see on the console that there is the data. The problem is just the rendering part.
import React, {Component} from 'react';
import {Container, Button, DropdownMenu, DropdownItem, Dropdown, DropdownToggle} from 'reactstrap';
import {Carousel} from 'react-responsive-carousel';
import styles from 'react-responsive-carousel/lib/styles/carousel.min.css';
import './selectHotel.css'
import Scroll from '../ScrollUp';
import {search} from '../../actions/search';
import {connect} from 'react-redux';
class SelectHotel extends Component{
constructor(props){
super(props);
this.state={
dropdownOpen: false,
hotels: []
};
this.toggleDropdown = this.toggleDropdown.bind(this);
}
static getDerivedStateFromProps(state, props){
if(props.hotels !== state.hotels)
return{
...state,
hotels: props.hotels
}
return null;
}
createCardHotels = () => {
return this.state.hotels.map((hotel) => {
return(
<div key={hotel._id} className="card">
<div className="row ">
<div className="col-md-4">
<Carousel autoPlay infiniteLoop>
<div>
<img src="https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400" className="w-100"/>
</div>
<div>
<img src="https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400" className="w-100"/>
</div>
<div>
<img src="https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400" className="w-100"/>
</div>
<div>
<img src="https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400" className="w-100"/>
</div>
<div>
<img src="https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400" className="w-100"/>
</div>
<div>
<img src="https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400" className="w-100"/>
</div>
<div>
<img src="https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400" className="w-100"/>
</div>
<div>
<img src="https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400" className="w-100"/>
</div>
</Carousel>
</div>
<div className="col-md-5 px-3">
<div className="card-block px-3">
<h3 className="card-title">{hotel.name}</h3>
<p className="card-text">description</p>
</div>
</div>
<div className="col-md-3 price">
<h1 className="reservation-price">$Price</h1>
<Button style={cssStyles.buttonRoom} bsStyle="primary">Choose Hotel</Button>
</div>
</div>
</div>
)}
)
}
toggleDropdown() {
this.setState(prevState => ({
dropdownOpen: !prevState.dropdownOpen
}));
}
render(){
console.log(this.state)
console.log(this.props)
return(
<div>
<Container>
<Scroll/>
<div>
<Dropdown className = 'sortbutton' size="lg" isOpen={this.state.dropdownOpen} toggle={this.toggleDropdown}>
<DropdownToggle style={{backgroundColor: "white", borderColor: "grey" , color: "black"}} caret>
Sort By:
</DropdownToggle>
<DropdownMenu>
<DropdownItem onClick={()=>{this.setSort("low");}}>
Price: Low to High
</DropdownItem>
<DropdownItem divider />
<DropdownItem onClick={()=>{this.setSort("high");}}>
Price: High to Low
</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
{this.createCardHotels()}
<br></br>
</Container>
</div>
);
}
}
const cssStyles = {
buttonRoom:{
backgroundColor: '#156bc1',
border: '1px solid #156bc1',
alignItems: 'left',
boxShadow: 'inset 0 -2px 0 #063665',
paddingLeft: '2rem',
paddingRight: '2rem',
fontSize: '0.8rem'
}
}
const mapStatetoProps = state => {
return {
hotels: state.search.hotels
};
}
export default connect(mapStatetoProps, {search})(SelectHotel);
EDIT:
This is the image from console after I put console.log(this.state), console.log(this.props), it seems like there is data in this.props and not in this.state

The issue is with add class names to JSX elements. You are using class to apply css styles with class names but class is reserved for creating class components in React so you need to use className
Wherever you see class on jsx elements change it to className
Also never forget to add key to the top parent jsx element when you render them in loop. If you have unique from data then set id from data as a key like I did below else use index as key
Change
return this.state.hotels.map((hotel) => {
return(
<div class="card">
........
To
return this.state.hotels.map((hotel) => {
return(
<div key={hotel.id} className="card">
.......
Also
Change
<h1 className="reservation-price">$Price</h1>
To
<h1 className="reservation-price">{"$Price"}</h1>
For images you need to use require or import
Change
<img src="https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400" className="w-100"/>
To
<img src={require("https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400")} className="w-100"/>
Do the same for other images as well
Or import it like
import text from "https://placeholdit.imgix.net/~text?txtsize=38&txt=400%C3%97400&w=400&h=400";
<img src={text} className="w-100"/>

Сould you please show your building file. May be a problem with file-loader.

Related

Why is my id failing in my React component?

I need some help with this code it is giving an error of 'id' not defined, can have some assistance.
import React from "react";
const ContactCard = (props) => {
return(
<div className="item">
<div className="content">
<div className="Header">{props.contact.name}</div>
<div>{props.contact.email}</div>
</div>
<i className="trash alternate outline icon"
style={{color:"red", marginTop: "7px"}}
onClick = {() => props.clickHander(id)} >
</i>
</div>
);
}
As a guess, I believe instead of using id, use props.contact.id. That's why undefined error coming for id.
Going a little further than this answer, While you're bringing in props you can also destructure props, example:
import React from 'react'
const ContactCard = ({contact, clickHander}) => {
return (
<div className='item'>
<div className='content'>
<div className='Header'>{contact.name}</div>
<div>{contact.email}</div>
</div>
<i className='trash alternate outline icon' style={{ color: 'red', marginTop: '7px' }} onClick={() => clickHander(contact.id)}></i>
</div>
)
}
export default ContactCard

I keep getting `handleColor` is not a function error

I have some problem with a function I set up to change the background color of a button when it is clicked.
I setup the function in a parent component below:
import React, { useRef, useState } from 'react';
import Aside from './Aside';
import Content from './Content';
const Dashboard = () => {
let asideRef = useRef(null);
const handleColor = color => {
asideRef.current.style.backgroundColor = color;
};
return (
<div className="d-flex flex-row" id="main_wrapper">
<Aside handleColor={handleColor} postedRef={asideRef} />
<Content />
</div>
);
};
export default Dashboard;
in the child component it is called in this manner:
import { Link } from 'react-router-dom';
import React, { createRef } from 'react';
class Aside extends React.Component {
constructor(props) {
super(props);
this.state = {
btn: true,
btnEn: true,
background: '#fff',
};
this.handleClick = this.handleClick.bind(this);
}
handleClick = () => {
const { btn } = this.state;
this.setState({
btn: !btn,
});
};
render() {
const { btn, btnEn, background } = this.state;
const { handleColor, postedRef } = this.props;
console.log(this.props);
return (
<div className="d-flex flex-column asidebar" id="aside_wrapper" style={{ width: '20%', height: '100vh' }}>
<div className="d-flex flex-row justify-content-center nav-header">
<a href="/dashboard" className="brand-logo">
<picture>
<img src="https://user-images.githubusercontent.com/25479050/99581983-c1c18e00-29e1-11eb-9bd3-4a53585456cb.png" className="img-fluid img-thumbnail" alt="plaschema logo" />
<source media="(min-width:650px)" srcSet="https://user-images.githubusercontent.com/25479050/99581983-c1c18e00-29e1-11eb-9bd3-4a53585456cb.png" type="image/svg+xml" />
<source media="(min-width:465px)" srcSet="https://user-images.githubusercontent.com/25479050/99582047-d736b800-29e1-11eb-92f3-83dce3912e39.png" type="image/svg+xml" />
</picture>
</a>
</div>
<div className="link_container d-flex flex-column">
<button type="button" className="buttonTrue" ref={postedRef} onClick={() => { handleColor('#f4f2f6'); }}>
<Link to="/">
<i className="lni lni-dashboard" />
<span className="link_name">Dashboard</span>
</Link>
</button>
<button type="button" className={btnEn ? 'buttonTrue' : 'buttonFalse'}>
<Link to="/enroll">
<i className="lni lni-tab" />
<span className="link_name">Enrollment</span>
</Link>
</button>
<Link className=" icons accreditation-wrapper" to="/accreditation">
<i className="lni lni-checkbox" />
<span className="link_name">Accreditation</span>
</Link>
<Link className=" icons subscription-wrapper" to="/subscription">
<i className="lni lni-tab" />
<span className="link_name">Subscription</span>
</Link>
<Link className=" icons service-wrapper" to="/service">
<i className="lni lni-control-panel" />
<span className="link_name">Service Usage</span>
</Link>
<Link className=" icons report-wrapper" to="/report">
<i className="lni lni-library" />
<span className="link_name">Reports</span>
</Link>
</div>
</div>
);
}
}
export default Aside;
After setup, anytime I click on the only button I set it up on as a test, I keep getting this error page handleColor is not a function. Right now I can't think of what the issue maybe because I have tried several approaches to get it to work but the error is still there. Below is the code of the component I am trying to apply it on:
Looking forward to helpful responses. Thanks.
The question has been updated for more insight. Sorry for the earlier issues with the first iteration.
you can try with
const handleClick = () => {
or
function handleClick () {
You're wrongly referring the handleColor. handleColor is not a prop, it is a component method, you can use like this.handleColor
const { handleColor } = this.props // this is wrong, it's not a prop method
<button type="button" className="buttonTrue" ref={this.colorSwitch} onClick={() => { this.handleColor('#f4f2f6'); // this is right }}>
<Link to="/">
<i className="lni lni-dashboard" />
<span className="link_name">Dashboard</span>
</Link>
</button>
I have created sample example here with some of your code. Check out this link

React Rotate Accordion Arrow Onclick

How can I rotate the arrows onclick
This is my code below for my react collapse and I would like to rotate the arrows of my collapse accordion when it clicked.
I'm using reactstrap to build it and react fontawsome for my Icons
I've also attached a .GIF Link to demonstrate how my accordion is currently functioning.
import React, { Component } from "react";
import { Collapse, CardBody, Card, CardHeader } from "reactstrap";
import { faChevronDown } from "#fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
const nested = [
{
id: 10,
title:"Customer Queries"
},
];
const Icon = <FontAwesomeIcon icon={faChevronDown} color={"#EB8C00" } />;
class Colapse extends Component {
constructor(props) {
super(props);
this.tog = this.tog.bind(this);
this.state = {
col: 0,
cards: [
{
id:1,
title:"General information requests",
sub_title:"Fault reports",
body:"Something to display for body 1",
},
{
id:2,
title:"Account queries",
sub_title:"Communication protocols",
body:"Something to display for body 2",
}
] };
}
tog(e) {
let event = e.target.dataset.event;
this.setState({
col: this.state.col === Number(event) ? 0 : Number(event),
});
}
render() {
const { col, cards } = this.state;
return (
<div className="container collapse-container">
{nested.map((element, index) => {
return (
<Card key={index} className="card rounded ">
<CardHeader
className="card-header"
onClick={this.tog}
data-event={(index = element.id)}
>
<p className="collapse d-flex">
<div className=" p-2 mr-auto font-weight-bold">
<p className="">{element.title}</p>
</div>
<a
class="click-layer"
onClick={this.tog}
data-event={index}
></a>
</p>
</CardHeader>
<Collapse isOpen={col !== index}>
<CardBody className="card-body">
<p className="card-text">Customer Queries relate to information, account or meter related faults reported by the customer.</p>
{/**HERE NESTED */}
{cards.map((index) => {
return (
<Card key={index} className="card-sub rounded ">
<p className="card-header-sub" >{index.title}</p>
<CardHeader
className="card-header-sub"
onClick={this.tog}
data-event={index.id}
>
<p className="colle d-flex">
<div className="p-2 rotate">{Icon}</div>
<div className=" p-2 mr-auto font-weight-bold">
<p className="card-header-sub">{index.sub_title}</p>
</div>
<a
class="click-layer"
onClick={this.tog}
data-event={index.id}
></a>
</p>
</CardHeader>
<Collapse isOpen={col === index.id}>
<CardBody className="card-body-sub">
<p className="card-text-body">{index.body}</p>
</CardBody>
</Collapse>
</Card>
);
})}
{/**End Of Nested */}
</CardBody>
</Collapse>
</Card>
);
})}
</div>
);
}
}
export default Colapse;
Rotate the svg according to some condition e.g. col === element.id
<div className={`p-2 rotate ${col === element.id ? "isRotated" : ""}`}>{Icon}</div>
on your stylesheet:
.isRotated svg {
transform: rotate(-90deg);
}

REACT : empty render despite no errors

I am using the Context API to manage state in a small app. I get the response OK, the Consumer has it, so I map through it and want to pass down data from it to a Product Card component through props. And the Product Card renders absolutely nothing. I get no errors whatsoever. Can anyone help me out please? Here is the code of parent component:
import Pagination from "./Pagination";
import { Consumer } from "../context";
export default class Browse extends Component {
render() {
return (
<Consumer>
{value => {
const { search } = value;
return (
<ProductsGrid>
{search.map(beer => (
<ProductCard
key={beer.id}
beerId={beer.id}
beerName={beer.name}
beerTagline={beer.tagline}
beerAbv={beer.abv}
firstBrewed={beer.first_brewed}
imageUrl={beer.image_url}
/>
))}
</ProductsGrid>
);
}}
</Consumer>
);
}
}`````
and here is the Product Card component:
```export default class ProductCard extends React.Component {
render() {
return (
<div className="product-card">
<div className="product-card-inner">
<div className="product-info-container">
<h1 className="beer-name">{this.props.beerName}</h1>
<p className="beer-type">{this.props.beerTagline}</p>
<p className="beer-alcohol">{this.props.beerAbv}%</p>
<p className="first-brewed">
First brewed: {this.props.firstBrewed}
</p>
</div>
<div className="beer-image-container">
<img src={this.props.imageUrl} alt="beer" />
</div>
<div className="price-container">
<h1>£ 3.50</h1>
</div>
<div className="button-container">
<div className="quantity-container">
<p className="minus-sign"> - </p>
<p className="qty-number"> 0 </p>
<p className="plus-sign"> + </p>
</div>
<div className="add-container">
<IoIosCart />
<p>Add</p>
</div>
</div>
</div>
</div>
);
}
}```

How to scroll to id after clicking on the internal Link in Gatsby.js

I am building a blog and after clicking on Link linking to an article I want the new page to be scrolled on the Title of the article.
I have tried to use <Link to={`/${node.slug}#blog-title`}>{node.title}</Link>
but it doesn't scroll to title, it scrolls back to top of the page.
I have tried to use window.scrollTo(document.getElementById('blog-title); in componentDidMount but it looks like it's not renered until then and it still goes to top. If I use setTimeout it only scrolls to top to straight away scroll to the correct id.
index.js
return (
<article className="blog-listing" key={node.slug}>
<div className="entry-meta-content">
<h2 className="entry-title">
<Link to={`/${node.slug}`}>{node.title}</Link>
</h2>
<span className="entry-meta">
Created on {node.publishDate} By {node.author.name}
</span>
</div>
<div className="entry-media">
<Img fluid={node.heroImage.fluid} backgroundColor="#f4f8fb" />
</div>
<div className="entry-content-bottom">
<p className="entry-content">{node.body.childMarkdownRemark.excerpt}</p>
<Link to={`/${node.slug}`} className="entry-read-more">
<span />
Read More
</Link>
</div>
</article>
);
blog-post.js
import React, { Component } from 'react';
import get from 'lodash/get';
import Helmet from 'react-helmet';
import { graphql } from 'gatsby';
import Img from 'gatsby-image';
import Template from '../components/layout';
class BlogPostTemplate extends Component {
render() {
const post = get(this, 'props.data.contentfulBlogPost');
return (
<Template>
<Helmet title={`${post.title}`} id="blog-title" />
<div className="inner-blog-post">
<div className="container">
<div className="row">
<div className="col-lg-12 col-md-12">
<div className="entry-media">
<Img fluid={post.heroImage.fluid} backgroundColor="#f4f8fb" />
</div>
<h1 className="section-headline"> {post.title} </h1>
<p> {post.publishDate} </p>
<div
dangerouslySetInnerHTML={{
__html: post.body.childMarkdownRemark.html
}}
/>
</div>
</div>
</div>
</div>
</Template>
);
}
}
export default BlogPostTemplate;
export const pageQuery = graphql`
query blogPostQuery($slug: String) {
contentfulBlogPost(slug: { eq: $slug }) {
title
body {
childMarkdownRemark {
html
}
}
heroImage {
file {
url
}
fluid(maxWidth: 1800) {
...GatsbyContentfulFluid_withWebp_noBase64
}
}
}
}
`;
Thanks!
In your blogpost.js, you're attaching an id to the <Helmet> tag, which doesn't generate any content in the body. Perhaps you should attach it to the title in the body instead?
...
<Template>
- <Helmet title={`${post.title}`} id="blog-title" />
+ <Helmet title={`${post.title}`} />
<div className="inner-blog-post">
<div className="container">
<div className="row">
<div className="col-lg-12 col-md-12">
<div className="entry-media">
<Img fluid={post.heroImage.fluid} backgroundColor="#f4f8fb" />
</div>
- <h1 className="section-headline"> {post.title} </h1>
+ <h1 id="blog-title" className="section-headline"> {post.title} </h1>
...

Resources