Create a new row every three columns - javascript

I am trying to create a virtual shop and I want to make every row of products have four items on a large screen, three in medium, and two in smell.
My problem is that I can’t come up with a way to make it that every four items I iterate the item list a new row will be created.
(I am getting the data from an API I created with Flask, the getting the data part works.)
Here is my code:
import React, { useState, useEffect } from "react";
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
function ShopItems () {
const [items, setItems] = useState([]);
useEffect(() => {
fetch('/api/items').then(res => res.json()).then(data => {
setItems(data.items);
});
}, []);
return(
<Container fluid>
<Row xs={6} md={4} lg={3}>
{
items.map((item) => (
<Col key={item.id}>{item.name}</Col>))
}
</Row>
</Container>
)
}
export default ShopItems;

You are using props incorrectly.
<Container fluid>
<Row>
<Col xs={6} md={4} lg={3}></Col>
</Row>
</Container>

Related

Can someone help me with my react app that runs in the localhost and doesn't display anything?

import React, { useState, useEffect } from 'react';
import { makeStyles } from '#mui/material/styles';
import { Grid, Typography, Link } from '#mui/material';
// We can use the makeStyles hook from MUI to create a custom styles object
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
}));
function App() {
const classes = useStyles();
const [data, setData] = useState(null); // we'll use this state variable to store the data we get from the API
useEffect(() => {
// This function will run when the component mounts (similar to componentDidMount in a class-based component)
// We'll use the fetch API to get data from the API
fetch('https://api.example.com/endpoint')
.then((response) => response.json())
.then((json) => {
setData(json);
});
}, []); // We pass an empty array as the second argument to useEffect to make sure it only runs once
return (
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Typography variant="h2">Hello BeyondMD!</Typography>
</Grid>
<Grid item xs={12}>
{/* Here, we use the Link component from MUI to create a link to a PDF file */}
<Link href="public\Resume+Template.pdf" target="_blank">
View my resume
</Link>
</Grid>
{data && (
<Grid item xs={12}>
{/* If we have data from the API, we can render it here */}
<Typography variant="body1">{data.someProperty}</Typography>
</Grid>
)}
</Grid>
</div>
);
}
export default App;
Im trying to display my resume that I have put in the public and also fetch data from a free API (I dont know where though). In the end it is giving me a blank page with the localhost.
I have tried almost everything I can find online. I want it to display a line of text and my resume and also data from a free API anywhere.

how i get querySelectorAll html elements in react?

I am using react with functional component. I also use react-bootstrap , I attached the react-bootstrap carousel , everything is fine with react-bootstrap, for some functionality, I want to get three divs in react , divs has same classes. I know if I use simple html css js then I easily do that,
querySelectorAll(".indicator-btn")
but i want this on react. How can I do that? please suggest me a best practices for that.
This is a my component , in the last i have three divs which i want for Dom.
import React, { useState } from "react";
import Cardcarousel from "./Cardcarousel";
import { Carousel } from "react-bootstrap";
import Brand1img from "../images/brand1.png";
import Airbnbimg from "../images/Airbnb.png";
import Microsoft from "../images/microsoft.png";
import { Row, Col } from "react-bootstrap";
function Carouselx() {
const [index, setIndex] = useState(0);
const handleSelect = (selectedIndex, e) => {
console.log(selectedIndex, "e=>", e);
setIndex(selectedIndex);
};
const isSlide = (slide) => {
console.log("slide no => " + slide);
console.log(this);
};
return (
<>
<div className="px-5 py-3">
<Carousel activeIndex={index} onSelect={handleSelect} onSlide={isSlide}>
<Carousel.Item>
<Row>
<Col>
<Cardcarousel
name="Technology UI/UX"
companylogo={Brand1img}
type="Full time job"
/>
</Col>
<Col>
<Cardcarousel
name="Technology Backend developer"
companylogo={Airbnbimg}
type="Part time job"
/>
</Col>
<Col>
<Cardcarousel
name="Technology Backend developer"
companylogo={Microsoft}
type="Internee"
/>
</Col>
</Row>
</Carousel.Item>
<Carousel.Item>
<Row>
<Col>
<Cardcarousel
name="Technology UI/UX"
companylogo={Brand1img}
type="Full time job"
/>
</Col>
<Col>
<Cardcarousel
name="Technology Backend developer"
companylogo={Airbnbimg}
type="Part time job"
/>
</Col>
<Col>
<Cardcarousel
name="Technology front end developer"
companylogo={Microsoft}
type="Internee"
/>
</Col>
</Row>
</Carousel.Item>
</Carousel>
<div className="carusel-indecator-container">
<div className="indicator-btn indicator-btn1"></div>
<div className="indicator-btn indicator-btn2"></div>
<div className="indicator-btn indicator-btn3"></div>
</div>
</div>
</>
);
}
export default Carouselx;
You could use useState to get its refs (also useRef but there'll be a lot more inconveniences potentially).
const [btn1, setBtn1] = useState();
const [btn2, setBtn2] = useState();
const [btn3, setBtn3] = useState();
...
<div ref={setBtn1} className="indicator-btn indicator-btn1"></div>
<div ref={setBtn2} className="indicator-btn indicator-btn2"></div>
<div ref={setBtn3} className="indicator-btn indicator-btn3"></div>
At some point (after 1st rendering) you'll have btn1, btn2, btn3 as button elements. If you want to use it, assumingly imperatively, you could useEffect
useEffect(() => {
if (!btn1 || !btn2 || !btn3) return;
// do something with these refs i.e. make them jquery! $(btn1)
}, [btn1, btn2, btn3]);

Creating dynamic responses to button clicks in React

I've been asked to create a FAQ page with a chatbot style. The way I'm trying to do this is by creating a paragraph element with some text along the lines of "Hello, ask me a question!" with five buttons in a row underneath containing the FAQs. The idea is that the user should be able to click on one of the buttons and reveal the answer to the question in a new paragraph element and the remaining 'unanswered' questions should appear in a row of buttons below that.
So far I've only managed to create an accordion style page where the questions are in a column and the answer is revealed when they're clicked on. This works but I'd really like to try to meet my brief and get a better understanding of React at the same time. My current code is below - any help would be appreciated!
import React, { useState } from 'react';
import classes from './Chat.module.css';
import { Container, Row, Col } from 'react-bootstrap';
const ChatItem = (props) => {
const [isOpen, setIsOpen] = useState(false);
const clickHandler = () => {
setIsOpen(true);
console.log(isOpen);
};
return (
<Container>
<Row md={5}>
<button className={classes.conversation_btn} onClick={clickHandler}>
{props.question}
</button>
</Row>
<Row>
<Col mdPush={7} md={5}>
<div
className={`${classes.text_box} ${
isOpen ? classes.open : classes.closed
}`}
>
{props.answer}
</div>
</Col>
</Row>
</Container>
);
};
const ChatList = (props) => {
return (
<div>
{props.items.map((item) => (
<ChatItem
key={item.id}
id={item.id}
question={item.question}
answer={item.answer}
/>
))}
</div>
);
};
export default ChatList;

Cannot read properties of undefined (reading 'map') in React

I'm trying to make a ecommerce site using the commerce.js library. I have already 8 products in the library API. I have a Products.js component where I'm passing those array of product objects I got from App.js and again passing single product object to the Product.js component. To do this, I'm using mapping function to pass each object as props to the Product.js component. And I'm receiving this error. I tried commenting out the mapping block and only console logged the products variable from App.js and the prop products in Products.js, there I'm getting all the 8 products so no problem in there. But I don't get it why I'm getting this error in the mapping function.
App.js
import React, { useState, useEffect } from "react";
import { commerce } from "./lib/commerce";
import { Products, Navbar } from "./components";
function App() {
const [products, setProducts] = useState([]);
const fetchProduct = async () => {
const data = await commerce.products.list();
setProducts(data);
};
useEffect(() => {
fetchProduct();
}, []);
console.log("products", products);
return (
<div className="App">
<Navbar />
<Products products={products} />
</div>
);
}
export default App;
Products.js
import React from "react";
import { Grid } from "#material-ui/core";
import Product from "./Product/Product";
import useStyles from "./style";
const Products = ({ products }) => {
const classes = useStyles();
return (
<main className={classes.content}>
<div className={classes.toolbar} />
<Grid container justifyContent="center" spacing={4}>
{products.data.map((product) => (
<Grid item key={product.id} xs={12} sm={6} md={4} lg={3}>
<Product product={product} />
</Grid>
))}
</Grid>
</main>
);
};
export default Products;
Product.js
import React from "react";
import {
Card,
CardMedia,
CardContent,
CardActions,
Typography,
IconButton,
} from "#material-ui/core";
import { AddShoppingCart } from "#material-ui/icons";
import useStyles from "./styles";
const Product = ({ product }) => {
const classes = useStyles();
return (
<Card className={classes.root}>
<CardMedia
className={classes.media}
image={product.media.source}
title={product.name}
/>
<CardContent>
<div className={classes.cardContent}>
<Typography variant="h5" gutterBottom>
{product.name}
</Typography>
<Typography variant="h5">
{product.price.formatted_with_symbol}
</Typography>
</div>
<Typography
variant="body2"
dangerouslySetInnerHTML={{ __html: product.description }}
/>
</CardContent>
<CardActions disableSpacing className={classes.cardActions}>
<IconButton aria-label="Add to Cart">
<AddShoppingCart />
</IconButton>
</CardActions>
</Card>
);
};
export default Product;
In your App.js change your fetchProduct function as follows:
const fetchProduct = async = {
const products = await commerce.products.list();
setProducts(products.data);
}
and then in your Products.js map over the products instead of products.data,
{products.map((product) => (
<Grid item key={product.id} xs={12} sm={6} md={4} lg={3}>
<Product product={product} />
</Grid>
))}
EXPLANATION:
The initial State of products is an empty array, which is passed down to the products component, where you tried products.data.map() but products is an array (initially) and there is no data property on arrays, so it threw error.
There are several ways you can get around this, but if you are only using the products data from the response then you can go with the above approach, where you map over the products not products.data and setProducts() with the products array instead of products object.
Do you can to attached screen with error?
I think, you try to read data before is are loading, you can prevent this by add something like this (products.data || []).map for example.. or change default state in App.js on useState({data:[]})

Auto scroll react redux implementation

I am implementing auto-scroll option for my application. In below case channels are list of data which fetch from database. I used redux to call api. how can i connect InfiniteScroll and channels list to get auto-scroll feature?
import React, { Fragment } from "react";
import { Grid } from "#material-ui/core";
import ChannelCard from "./Card";
import CreateChannel from "./Create";
import SimpleSelect from "./Filter";
import InfiniteScroll from "react-infinite-scroll-component";
const ChannelList = ( {channels: { channels}}) => {
const [data, setData] = React.useState({
items: Array.from({ length: 20 })
});
const { items } = data;
const fetchMoreData = () => {
// a fake async api call like which sends
// 20 more records in 1.5 secs
setTimeout(() => {
setData({
items: items.concat(Array.from({ length: 20 }))
});
}, 1500);
};
//view
const view = (
<Fragment>
<Grid container>
<Grid item xs={6} sm={6} md={10} lg={10} xl={10}></Grid>
<Grid>
<SimpleSelect />
</Grid>
</Grid>
<Fragment>
<InfiniteScroll
dataLength={items.length}
next={fetchMoreData}
hasMore={true}
loader={<h4>Loading...</h4>}
>
<Grid container>
{channels.map(channel => (
<Grid key={channel._id} item xs={6} sm={6} md={3} lg={2} xl={2}>
<ChannelCard
channel={channel}
isAuthenticated={isAuthenticated}
/>
</Grid>
))}
</Grid>
</InfiniteScroll>
</Fragment>
</Fragment>
);
return <Fragment>{view}</Fragment>;
};
export default ChannelList;
(I used redux to call api. how can i connect InfiniteScroll and channels list to get auto-scroll feature?)
InfiniteScroll component requires the children to be the array of components that you want to have infinite scrolling on, since you have only one child which is the Grid component it is doing its job for only one item hence its not working: https://www.npmjs.com/package/react-infinite-scroll-component
just remove the wrapping Grid component
<InfiniteScroll
dataLength={items.length}
next={fetchMoreData}
hasMore={true}
loader={<h4>Loading...</h4>}
>
{channels.map(channel => (
<Grid key={channel._id} item xs={6} sm={6} md={3} lg={2} xl={2}>
<ChannelCard
channel={channel}
isAuthenticated={isAuthenticated}
/>
</Grid>
))}
</InfiniteScroll>

Categories

Resources