How do I use useRef to Open ActionSheet with Details - javascript

I am having a single fruit with a list of infestations that I'm mapping on my react component. I want to open an ActionSheet with the details of an individual infestation when it is clicked. I have tried this way but its not working. Anyone, please help.
import React, { useState, useEffect, useRef } from "react";
import { Link, useNavigate, useParams } from "react-router-dom";
import Menubar from "../../components/menubar/Menubar";
import Tabs from "../../components/fruittabs/FruitTabs";
import WidgetSkeleton from "../../components/skeleton/WidgetSkeleton"
import Skeleton from "react-loading-skeleton";
import toast, { Toaster } from 'react-hot-toast';
import axios from 'axios';
import InfestationWidget from "../../components/widgets/InfestationWidget"
import ActionSheet from "actionsheet-react";
import { LazyLoadImage } from "react-lazy-load-image-component";
function FruitDetails() {
let navigate = useNavigate();
const [fruit, setFruit] = useState({});
const { fruitId } = useParams();
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
let isMounted = true;
axios.get(`/api/fruit/${fruitId}`).then(res => {
if (isMounted) {
if (res.data.status === 200) {
setFruit(res.data.fruit);
setIsLoading(false);
}
else if (res.data.status === 404) {
toast.error(res.data.message, "error");
}
}
});
return () => {
isMounted = false
};
}, []);
const ref = useRef(fruit.infestation && fruit.infestation.infestationid);
const handleOpen = () => {
ref.current.open();
console.log(`Fruit Infestation id: ${fruit.infestation.infestationid}`);
};
const handleClose = () => {
ref.current.close();
}
return (
<div>
<Menubar />
<div className="appHeader bg-primary text-light">
<div className="left">
<a onClick={() => navigate(-1)} className="headerButton goBack">
<i className="fi fi-rr-angle-left"></i>{" "}
</a>
</div>
<div className="pageTitle">{fruit.name}</div>
<div className="right"></div>
</div>
<Toaster />
<div id="appCapsule">
<div className="section mt-3 mb-3">
{isLoading ?
<Skeleton height={150} /> :
<LazyLoadImage
effect="blur"
width={'100%'}
src={`${process.env.REACT_APP_API_URL}/storage/fruits/${fruit.image}`}
alt="image"
className="imaged img-fluid fruit-detail-main"
/>}
</div>
<div className="section mt-3 mb-3">
<div>
<Tabs>
<div label="Details">
{isLoading && (
<Skeleton height={25} count="8" className="mb-05" />
)}
<div
dangerouslySetInnerHTML={{
__html: fruit.description,
}}
/>
</div>
<div label="Infestations">
<div className="mb-1">Here are some of the Popular Infestations for {fruit.name}</div>
<h3 className="mb-1">All Infestations</h3>
<div className="row">
{isLoading && <WidgetSkeleton cards={6} />}
{fruit.infestation && fruit.infestation.map((infestation) => (
<div className="col-6" infestation={infestation} key={infestation.infestationid}>
<div className="card mb-2">
<a onClick={handleOpen}>
<LazyLoadImage
src={`${process.env.REACT_APP_API_URL}/storage/infestations/${infestation.infestationimage}`}
className="card-img-top" alt="image" />
<div className="card-body card-bodysmall">
<p className="mb-0 text-sm-x">{infestation.infestationtype}</p>
<h4 className="mb-0">{infestation.infestationname}</h4>
</div>
</a>
</div>
</div>
))}
</div>
</div>
<div label="Advice">
<div
dangerouslySetInnerHTML={{
__html: fruit.advice,
}}
/>
</div>
</Tabs>
<ActionSheet
ref={ref}
sheetStyle={{
borderTopLeftRadius: 15,
borderTopRightRadius: 15,
height: '80%'
}}>
<div className="bar" />
//Single Fruit Infestation Details
</ActionSheet>
</div>
</div>
</div>
</div>
);
}
export default FruitDetails;

Related

Showing Item details in Reactjs component using Laravel API

I have a list of fruits I want show their details. I have built the cards to display the list, and now I want to build a page that shows details for every item and open up its corresponding card list is clicked. I keep getting an error
TypeError: Cannot read properties of undefined (reading 'name')
The list cards work fine, and the individual item api also works fine. But now I cant display the details. Kindly help.
The Card Component
import React from 'react';
import { Link } from "react-router-dom";
import { LazyLoadImage } from "react-lazy-load-image-component";
const FruitWidget = ({ fruit }) => {
return (
<div className="col-6">
<div className="card mb-2">
<Link to={"/fruit-details/"+fruit.id}>
<LazyLoadImage src="assets/img/sample/photo/product1.jpg"
className="card-img-top lazycolor" alt="image" />
<div className="card-body">
<h4 className="mb-0">{fruit.name}</h4>
</div>
</Link>
</div>
</div>
);
}
export default FruitWidget;
The Items List
import React, { useState, useEffect } from 'react';
import { useNavigate } from "react-router-dom";
import Menubar from "../../components/menubar/Menubar"
import FruitWidget from "../../components/widgets/FruitWidget"
import { LazyLoadImage } from "react-lazy-load-image-component";
import WidgetSkeleton from "../../components/skeleton/WidgetSkeleton"
function Training() {
let navigate = useNavigate();
const [fruits, setFruits] = useState([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetch("http://localhost:8000/api/fruits")
.then((result) => result.json())
.then((fruits) => {
setFruits(fruits);
setIsLoading(false);
});
}, []);
console.warn("result", fruits)
return (
<div className="section">
<div className="row">
{isLoading && <WidgetSkeleton cards={6} />}
{fruits.map((fruit) => (
<FruitWidget fruit={fruit} key={fruit.id} />
))}
</div>
</div>
);
}
export default Training;
The Details Component
import React, { useState, useEffect } from 'react';
import { useNavigate, useParams } from "react-router-dom";
import Menubar from "../../components/menubar/Menubar"
import Tabs from "../../components/fruittabs/FruitTabs";
function FruitDetails() {
let navigate = useNavigate();
const [fruit, setFruit] = useState({});
const { fruitId } = useParams();
useEffect(() => {
fetch(`http://localhost:8000/api/fruit/${fruitId}`)
.then((result) => result.json())
.then((fruit) => {
setFruit(fruit[0]);
});
}, [fruitId]);
return (
<div>
<Menubar />
<div className="appHeader bg-primary text-light">
<div className="left">
<a onClick={() => navigate(-1)} className="headerButton goBack">
<i className="fi fi-rr-angle-left"></i> </a>
</div>
<div className="pageTitle">{fruit.name}</div>
<div className="right"></div>
</div>
<div id="appCapsule">
<div className="section mt-3 mb-3">
<img src="assets/img/lazyload.svg"
alt="image" className="imaged img-fluid fruit-detail-main" />
</div>
<div className="section mt-3 mb-3">
<div>
<Tabs>
<div label="Details">
{fruit.details}
</div>
<div label="Infestations">
After 'while, <em>Crocodile</em>!
</div>
<div label="Advice">
Nothing to see here, this tab is <em>extinct</em>!
</div>
</Tabs>
</div>
</div>
</div>
</div>
);
}
export default FruitDetails;

Each child in a list should have a unique "key" prop console error

Please help! I don't know why I'm getting this error. I can't find what I need to change :( The needed output in browser is perfectly fine. But I am getting this error. I'm not used to list and keys on react. I have the latest versions of React and Nodejs and the packages needed
Homescreen.js:
import React, { useState, useEffect } from 'react'
import axios from 'axios';
import Room from '../components/Room';
import Loader from '../components/Loader';
import Error from '../components/Error';
function Homescreen() {
let [rooms, setrooms] = useState([]);
const [loading, setloading] = useState();
const [error, seterror] = useState();
useEffect(() => {
async function getResults() {
try {
seterror(false);
setloading(true);
const data = (await axios('/api/rooms/getallrooms')).data;
setrooms(data);
setloading(false);
} catch (e) {
seterror(true);
setloading(false);
}
}
getResults();
}, []);
return (
<div className='container'>
<div className='row justify-content-center mt-5'>
{loading ? (
<Loader />
) : rooms.length > 1 ? (
rooms.map(room => {
return <div className="col-md-9 mt-3">
<Room room={room} />
</div>;
})
) : (
<Error />
)}
</div>
</div>
)
}
export default Homescreen;
//<h1>{room.name}</h1>
and my Room.js:
import React, { useState } from "react";
import { Modal, Button, Carousel } from 'react-bootstrap'
import { First } from "react-bootstrap/esm/PageItem";
import { Link } from 'react-router-dom'
function Room({ room }) {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
< div className="row bs" >
<div className="col-md-4">
<img src={room.imageurls[0]} className="smallimg" />
</div>
<div className="col-md-7">
<h1>{room.name}</h1>
<b>
{" "}
<p>Max Count : {room.maxcount}</p>
<p>Phone Number : {room.phonenumber}</p>
<p>Type : {room.type}</p>
</b>
<div style={{ float: "right" }}>
<Link to={`/book/${room._id}`}>
<button className="btn btn-primary m-5">Book Now!</button>
</Link>
<button className="btn btn-primary" onClick={handleShow}>View Details</button>
</div>
</div>
<Modal show={show} onHide={handleClose} size='lg'>
<Modal.Header>
<Modal.Title>{room.name}</Modal.Title>
</Modal.Header>
<Modal.Body>
<Carousel prevLabel='' nextLabel=''>
{room.imageurls.map(url => {
return <Carousel.Item>
<img
className="d-block w-100 bigimg"
src={url}
/>
</Carousel.Item>
})}
</Carousel>
<p>{room.description}</p>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</div>
);
}
export default Room;
Browser Console Error:
You have to give the first element in a map function a key:
rooms.map((room, index) => {
return (
<div key={index} className="col-md-9 mt-3">
<Room room={room} />
</div>
);
});

How can i use useParams() with an onClick button to navigate to different pages and display the data in react.js?

I'm working on a billing app. I have managed to fetch the Products from an API..... But now I'm trying to use useParams() to navigate to random pages that would display the items according to the ID by pressing a button...the navigation works fine but it wont display the data of that passed ID, it displays all the data in my API.
I would really appreciate some help or feedback, Thanks !
Item.js:
import React, { useEffect } from "react";
import { connect } from "react-redux";
import { getItems } from "../store/actions/itemsActions";
import { Link } from "react-router-dom";
import "./Items.css";
function Items({ getItems, items }) {
useEffect(() => {
getItems();
}, []);
function getRandomElFromArray(items) {
return Math.floor(Math.random() * items);
}
return (
<div>
<div className="container">
<div
className="image"
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: 200,
width: 100,
}}
>
<img src="http://i.stack.imgur.com/yZlqh.png" alt="" />
</div>
</div>
<div>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<div className="item-preview">
{items &&
items.items &&
items.items.map((item) => (
<div key={item.id}>
<h4>
ID:<Link to={`/bills/${item.id}`}> {item.id}
<button className="button4">Analyse Receipt</button>
</Link>
</h4>
</div>
))}
</div>
</div>
</div>
</div>
);
}
const mapStateToProps = (state) => {
return {
items: state.items,
};
};
const mapDispatchToProps = (dispatch) => {
return {
getItems: () => dispatch(getItems()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Items);
Billing.js:
import React, { useState } from "react";
import "./Bill.css";
import { Link, useParams, Switch, Route } from "react-router-dom";
import { connect } from "react-redux";
import { getItems } from "../store/actions/itemsActions";
function BillList({ items }) {
const [counter, setCounter] = useState(1);
const { id } = useParams();
function Display(props) {
return <label style={{ marginLeft: ".5rem" }}>{props.message}</label>;
}
return (
<div className="bills">
<div className="explore-container">
{items &&
items.items &&
items.items.filter((item) => item.id === id)
.map((item) => (
<div className="item-list" key={item.id}>
<h2>Title: {item.title}</h2>
<h4>price: {item.price}</h4>
</div>
))}
</div>
<div
className="main-title"
style={{
textAlign: "center",
justifyContent: "center",
alignItems: "center",
fontSize: 14,
}}
>
<h1>Bakery</h1>
<h1>Company Gbr</h1>
<h1>Oranienburger Straße 120</h1>
<h1>10119 Berlin</h1>
</div>
<div className="bills-container">
<div></div>
{/* pass in the details */}
<div className="item-list">
{items &&
items.items &&
items.items.map((item) => (
<React.Fragment key={item.id}>
<div className="bill-time">
<div className="bill">
<h4>
{" "}
<strong>Bill: </strong>
{item.billNumber}
</h4>
</div>
<div className="time">
<h4>
{" "}
<strong>Time: </strong>
{item.created_datetime}
</h4>
</div>
</div>
----------------------------------
----------------------------------
---------------------------------- --------------------
{/* Counter */}
<div className="price-total">
<div className="title">
<h3>
{" "}
<strong>Title: </strong>
{item.title}
</h3>
<div className="counter">
<strong>
<Display message={counter} />x
</strong>
</div>
</div>
<div className="increase">
<button onClick={() => setCounter(counter + 1)}>+</button>
</div>
<div className="decrease">
<button onClick={() => setCounter(counter - 1)}>-</button>
</div>
{/* Price and total */}
<div className="price">
<h4>
<strong>Price: {parseFloat(item.price)}€</strong>
</h4>
</div>
<div className="total">
<h4>Total: {parseFloat(item.price * counter)}€</h4>
</div>
</div>
</React.Fragment>
))}
</div>
{/* <div>
<h4>
Table: Counter
Terminal:
Ust-Id: DE11111111</h4>
</div> */}
</div>
<div className="button-path">
<Link to="/items">
<div className="button">
<button className="main-button">Analyse Receipt</button>
</div>
</Link>
</div>
<Switch>
<Route path="/bills/:id" />
</Switch>
</div>
);
}
const mapStateToProps = (state) => {
return {
items: state.items,
};
};
const mapDispatchToProps = (dispatch) => {
return {
getItems: () => dispatch(getItems()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(BillList);
The ":" of path="/bills/:id" is only used to designate id as a route parameter, it isn't meant to be part of any URL. When you link to to={`/bills/:${items.id}`} you are adding ":" to the id string value.
Remove it from the link. You should also ensure that the Items component has items to map, where each specific item mapped renders the link/button to link to the appropriate bill list page.
<Link to={`/bills/${item.id}`}>
<button className="button4">Analyse Receipt</button>
</Link>
The Items route also doesn't specify any route params, so there will be be none in the `Items component.
<Route exact path="/" component={Items} />

React error : Invalid prop `class` supplied to React.Fragment

enter image description here
Hello, we are currently experiencing the following errors in React. I'm not sure what's wrong with this error and it's being sent out. I tried to cover it with a tag instead of a <React.Fragment>, but the error above keeps appearing on the screen.
I think you're saying the wrong value is in the wrong tag. but I think, not found a problem with my code.
What could be wrong? I ask for your help me.
I attach my code.
import React, { useEffect, Fragment } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Helmet } from "react-helmet";
import {
POST_DETAIL_LOADING_REQUEST,
POST_DELETE_REQUEST,
USER_LOADING_REQUEST,
} from "../../redux/types";
import { Button, Row, Col } from "reactstrap";
import { Link } from "react-router-dom";
import CKEditor from "#ckeditor/ckeditor5-react";
import GrowingSpinner from "../../components/spinner/Spinner";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import {
faPencilAlt,
faCommentDots,
faMouse,
} from "#fortawesome/free-solid-svg-icons";
import BallonEditor from "#ckeditor/ckeditor5-editor-balloon/src/ballooneditor";
import BalloonEditor from "#ckeditor/ckeditor5-editor-balloon/src/ballooneditor";
import { editorConfiguration } from "../../components/editor/EditorConfig";
const PostDetail = (req) => {
const dispatch = useDispatch();
const { postDetail, creatorId, title, loading } = useSelector(
(state) => state.post
);
const { userId, userName } = useSelector((state) => state.auth);
console.log(req);
useEffect(() => {
dispatch({
type: POST_DETAIL_LOADING_REQUEST,
payload: req.match.params.id,
});
dispatch({
type: USER_LOADING_REQUEST,
payload: localStorage.getItem("token"),
});
});
const onDeleteClick = () => {
dispatch({
type: POST_DELETE_REQUEST,
payload: {
id: req.match.params.id,
token: localStorage.getItem("token"),
},
});
};
const EditButton = (
<div>
<Row className="d-flex justify-content-center pb-3">
<Col className="col-md-3 mr-md-3">
<Link to="/" className="btn btn-primary btn-block">
Home
</Link>
</Col>
<Col className="col-md-3 mr-md-3">
<Link
to={`/post/${req.match.params.id}/edit`}
className="btn btn-success btn-block"
>
Edit Post
</Link>
</Col>
<Col className="col-md-3">
<Button className="btn-block btn-danger" onClick={onDeleteClick}>
Delete
</Button>
</Col>
</Row>
</div>
);
const HomeButton = (
<div>
<Row className="d-flex justify-content-center pb-3">
<Col className="col-sm-12 com-md-3">
<Link to="/" className="btn btn-primary btn-block">
Home
</Link>
</Col>
</Row>
</div>
);
const Body = (
<div>
{userId === creatorId ? EditButton : HomeButton}
<Row className="border-bottom border-top border-primary p-3 mb-3 d-flex justify-content-between">
{(() => {
if (postDetail && postDetail.creator) {
return (
<div>
<div className="font-weight-bold text-big">
<span className="mr-3">
<Button color="info">
{postDetail.category.categoryName}
</Button>
</span>
{postDetail.title}
</div>
<div className="align-self-end">{postDetail.creator.name}</div>
</div>
);
}
})()}
</Row>
{postDetail && postDetail.comments ? (
<div>
<div className="d-flex justify-content-end align-items-baseline small">
<FontAwesomeIcon icon={faPencilAlt} />
<span> {postDetail.date}</span>
<FontAwesomeIcon icon={faCommentDots} />
<span>{postDetail.comments.length}</span>
<FontAwesomeIcon icon={faMouse} />
<span>{postDetail.views}</span>
</div>
<Row className="mb-3">
<CKEditor
editor={BalloonEditor}
data={postDetail.contents}
config={editorConfiguration}
disabled="true"
/>
</Row>
</div>
) : (
<h1>hi</h1>
)}
</div>
);
return (
<div>
<Helmet title={`Post | ${title}`} />
{loading === true ? GrowingSpinner : Body}
</div>
);
};
export default PostDetail;
It seems to be a small syntax error, your final return statement should be :
return (
<div>
<Helmet title={`Post | ${title}`} />
{loading === true ? <GrowingSpinner /> : <Body />}
</div>
);

reverse my data while showing to frontend side is not working why..?

Here is my reactjs code I want to reverse my data and display on slient side but reverse() is not working what to do..? I don't understand why is this happing with my code..! can anyone help me to reverse my data and display frontend(client side) ....! please help
import React, { useEffect, useState } from "react";
import { getBlogs } from "../helper/coreapicalls";
import ImageHelper from "../helper/ImageHelper";
import { Link } from "react-router-dom";
import Footer from "../Footer/Footer";
const Blog = (blog) => {
const [blogs, setBlog] = useState([]);
const [error, seterror] = useState(false);
useEffect(() => {
loadBlog();
}, []);
const loadBlog = () => {
getBlogs().then((data) => {
if (data.error) {
seterror(data.error);
} else {
setBlog(data);
// console.log(data);
}
});
};
// console.log(blogs);
return (
<div>
<div className="container py-md-5 py-3">
<h1 className="blog_heading">ALL BLOGS</h1>
<div className="row">
{blogs.reverse().map((blog, index) => (
<div className="col-lg-4 col-md-6 col-12" key={index}>
<Link to={`/blog/${blog._id}`} className="Blog_card_link">
<div className="card my-2 shadow">
<ImageHelper blog={blog} />
<div className="card-body">
<h5 className="card-title">
{blog.title.substring(0, 75) + " ..."}
</h5>
<div
className="description"
dangerouslySetInnerHTML={{
__html: blog.description.substring(0, 100) + " ...",
}}
/>
<Link
type="btn"
to={`/blog/${blog._id}`}
className="forMore_btn "
>
For More
</Link>
</div>
</div>
</Link>
</div>
))}
</div>
</div>
<Footer />
</div>
);
};
export default Blog;
Here is image of Frontend ( client side )
enter image description here
Yep! Try reversing your data when you set the state: setBlog(data.reverse()));

Categories

Resources