Reputation: 256
I am having this problem which I can not solve. So basically I have 2 components here Component A and Component G I have more of them but they are pretty much the same(concept is the same). I have a Link in Component G, A which when I click it, it brings me to the Payment Component. Tt now renders the (ImageA, ClassA and PriceA) its hard coded. Anyway what I am trying to achieve is that when I click for example on the Component G it renders only that (imageG, classG and priceG), so I would need it to filter it somehow or split the data somehow in the json file I imagine, but I dont know how to do it. I hope one of you fellow comrades will help me.
Payment Component
const Payment = ({
history,
location: { state },
match: {
params: { dataId }
}
}) => {
if (!state?.postData) {
history.goBack();
}
const { postData } = state;
return (
<div className="ml-20">
<img
alt=""
className="w:2/4 object-contain "
src={postData.imageG}
/>
<h2
className=" ml-24 mlg:ml-6 mlg:mt-2 mlg:static text-5xl mlg:text-2xl text-blue-400 absolute top-
48" >
{postData.classG}
</h2>
<h3
className="text-lg mlg:mb-2 mlg:ml-6 mlg:mt-2 mlg:static font-bold text-green-800
font-mono ml-24 top-64 absolute"
>
{postData.priceG}
</h3>
</div>
);
};
export default Payment
A COMPONENT
import React from "react";
import data from "../data.json";
import { Link } from "react-router-dom";
function A() {
return (
<div className='bg-black '>
{data.filter(d =>
d.classA &&
d.imageA &&
d.priceA)
.map((postData) => {
return (
<div className='bg-black' key={postData.id} >
<div className='bg-black '>
<img
alt=""
className="w-full object-contain "
src={postData.imageA}
></img>
<h1 className=" ml-24 mlg:ml-6 mlg:mt-2 mlg:static text-5xl mlg:text-2xl text-red-600
absolute top-48">
{postData.classA}
</h1>
<h1 className="text-lg mlg:mb-2 mlg:ml-6 mlg:mt-2 mlg:static font-bold text-yellow-600
font-mono ml-24 top-64 absolute" >
{postData.priceA}
</h1>
<Link
to={{pathname: `/payment/${postData.id}`,
state: {
postData,
},
}}
className="py-1 px-2 mlg:ml-6 mlg:mt-14 mlg:static text-black-600 h-8 ml-24 top-72 bg-
white w-32 text-center text-gray-red
rounded-full focus:outline-none focus:ring-2 focus:ring-gray-600 absolute"
>
Buy Now
</Link>
</div>
</div>
</div>
)
}
export default A
G Component
import React from "react";
import data from "../data.json";
import { Link } from "react-router-dom";
function G() {
return (
<div className='bg-black '>
{data.filter(d =>
d.classG &&
d.imageG &&
d.priceG)
.map((postData) => {
return (
<div className='bg-black' key={postData.id} >
<div className='bg-black '>
<img
alt=""
className="w-full object-contain "
src={postData.imageG}
></img>
<h1 className=" ml-24 mlg:ml-6 mlg:mt-2 mlg:static text-5xl mlg:text-2xl text-red-600
absolute top-48">
{postData.classG}
</h1>
<h1 className="text-lg mlg:mb-2 mlg:ml-6 mlg:mt-2 mlg:static font-bold text-yellow-600
font-mono ml-24 top-64 absolute" >
{postData.priceG}
</h1>
<Link
to={{pathname: `/payment/${postData.id}`,
state: {
postData,
},
}}
className="py-1 px-2 mlg:ml-6 mlg:mt-14 mlg:static text-black-600 h-8 ml-24 top-72 bg-
white w-32 text-center text-gray-red
rounded-full focus:outline-none focus:ring-2 focus:ring-gray-600 absolute"
>
Buy Now
</Link>
</div>
</div>
</div>
)
}
export default G
Json file
[
{
"id":0,
"classG":"G-Class",
"imageG":"./ModImages/Gclass.jpg",
"priceG":"Starting at $154,900",
"newG":"A 12.3-inch digital gauge cluster is newly standard across the
board, as are heated front seats. Plus, the sedan can be had with a Night
package that adds black exterior trim.",
"imageGIn":"./ModImages/GclassIn.jpg",
"imageCOut":"./ModImages/GclassOut.jpg",
"infoDesignC1":"How many technological breakthroughs can you fit into a C-
Class? With the advanced, powerful and sporty 2020 C 300 Wagon, plenty. From
its LED headlamps to its generous cargo hold, you'll find countless
refinements, and so many reasons it's a wagon like no other.",
"infoDesignG" :"The acclaimed C-Class cabin is as functional as it is
beautiful. Abundant innovations harmonize with five options in hand-finished
wood trim. A 12.3-inch digital instrument cluster and 10.25-inch centre
screen are available.",
"imageGIn1":"./ModImages/CclassIn1.jpg",
"imageGOut1":"./ModImages/CclassOut1.jpg",
"infoDesign2": "The Star on the outside is earned on the inside. The roomy,
refined cabin includes heated front seats and a driver-seat memory. Dual-
zone, double-filtered climate control. A panoramic sunroof. And options from
Burmester® surround sound to new Climate Comfort front seats.",
"infoInov": "Available Apple CarPlay™ and Android Auto let you enjoy more
from your own smartphone. Another navigation option is COMAND, which brings
you voice control not only for navigation and audio, but also many cabin
features.",
"imageInov1":"./ModImages/GclassInov1.jpg",
"imageInov2":"./ModImages/GclassInov2.jpg",
"infoInov1": "Available wireless charging lets you refuel your compatible
phone's battery as you drive. Easy-connect NFC pairing links your phone
every
time you get in. Apple CarPlay™ and Android Auto are available, too. And
four USB-C ports are standard.",
"infoInov2": "DYNAMIC SELECT lets you fine-tune your A-Class with the tap of
a console button. Four modes vary shift points, throttle response, steering
feel and more: efficient ECO, everyday Comfort, sharpened Sport, and create-
your-own Individual.",
"imageInov":"./ModImages/GclassInov.jpg",
"imageInov4":"./ModImages/GclassInov4.jpg" ,
"infoInov4G": "From the everyday to the unexpected, Mercedes me connect helps
ease your way. You can control vehicle features from your smartphone
(including Remote Start), set up a service appointment, and more. You can
also add In-car Wi-Fi for a low monthly rate. ",
"infoInov5C":"Available driver assists help de-stress driving, changing lanes
with a tap of your finger, and knowing to slow for a tollboth or exit. A
network of sensors keeps a constant lookout for danger ahead, even if it's
coming from behind."
},
{
"id":1,
"classA":"A-Class",
"imageA":"./ModImages/Aclass.jpg",
"priceA":"Starting at $54,900",
"newA":"In addition to a new 18-inch wheel design, the 2021 A-class gains
standard blind-spot monitoring and an optional gesture control feature for
the MBUX infotainment system.",
"imageAIn":"./ModImages/AclassIn.jpg",
"imageAOut":"./ModImages/AclassOut.jpg",
"infoDesignA":"A is for attention-getting. The clean lines, LED lighting and
aggressive stance of the A-Class Sedan are designed to capture admiring eyes.
Its ultramodern cabin and premium appointments aim to captivate its driver
and passengers for years to come.",
"infoDesignA1" :"With 100% LED lighting standard, inside and out, the A-Class
shines day or night, coming or going, and staying, too. Options include
MULTIBEAM LED headlamps and 64-colour ambient cabin lighting.",
"imageAIn1":"./ModImages/AclassIn1.jpg",
"imageAOut1":"./ModImages/AclassOut1.jpg",
"infoDesignA2": "The Star on the outside is earned on the inside. The roomy,
refined cabin includes heated front seats and a driver-seat memory. Dual-
zone, double-filtered climate control. A panoramic sunroof. And options from
Burmester® surround sound to new Climate Comfort front seats.",
"infoInov": "A is for advanced. With the Mercedes-Benz User Experience
(MBUX), the A-Class drives a new generation of user-friendly tech. Quite
possibly the most capable, natural and intuitive speech interface from any
automaker, it's easy to learn because it learns you.",
"imageInov1":"./ModImages/AclassInov1.jpg",
"imageInov2":"./ModImages/AclassInov2.jpg",
"infoInov1": "Available wireless charging lets you refuel your compatible
phone's battery as you drive. Easy-connect NFC pairing links your phone
every time you get in. Apple CarPlay™ and Android Auto are available, too.
And four USB-C ports are standard. Disclaimer[6] Disclaimer",
"infoInov2": "DYNAMIC SELECT lets you fine-tune your A-Class with the tap of
a console button. Four modes vary shift points, throttle response, steering
feel and more: efficient ECO, everyday Comfort, sharpened Sport, and create-
your-own Individual.",
"imageInov3":"./ModImages/AclassInov3.jpg",
"imageInov4":"./ModImages/AclassInov4.jpg" ,
"infoInov4": "Get up close with the A-Class Sedan in this captivating ASMR audio experience. "
}
]
Upvotes: 1
Views: 113
Reputation: 640
I'm updating the answer based on the comments
First thing, I would make sure my JSON properties are consistent across objects:
[
{
"id":0,
"class":"G-Class",
"image":"./ModImages/Gclass.jpg",
"price":"Starting at $154,900",
"new":"Mercedes-Benz introduces a mid-cycle update of the E-class lineup for 2021. The changes
apply",
"infoInov": "....",
"imageOut": "..."
},
{
"id":1,
"class":"A-Class",
"image":"./ModImages/Aclass.jpg",
"price":"Starting at $54,900",
"new":"Mercedes-Benz introduces a mid-cycle update of the E-class lineup for 2021. The changes
apply",
"infoInov": "....",
"imageOut": "..."
}
]
Since all the properties are consistent, the only way you can consistently tell them apart is by the id
property. If id === 0
, we know it's the G. if === 1
, we know it's A, and so on.
This way, I can use only one component to render them both. If you want to apply different styles or render something if it's component G, you can do something like:
function AG() {
return (
<div className="bg-black">
{data.map(product => (
<div>
<img src={product.image} />
<h1>{product.class}</h1>
<h1 className={product.id === 0 ? 'g-class' : ''}>{product.price}</h1>
<Link to={`/payment/${product.id}` />
{product.id === 0 && <div>This will only appear to G</div>}
</div>
))}
</div>
)
}
Notice above that I have some checks to apply styles or render something only if product.id === 0
. This is one of the ways to reuse a component and apply little changes to it.
In the <Link>
we are sending the user to /payments
passing the productID in the path. So inside the Payments
component, you would use this productID to filter the data from the JSON.
Now in the Payment component, you can just import the same JSON data
and filter by the id
we are passing in the URL path:
import data from "../data.json"
const Payment = () => {
// get the id from the URL somehow, I suppose you are using react router
// this is just an example
const { idFromURL } = match.param
const filteredProduct = data.filter(product => product.id === idFromURL)
return (
<div>
<img src={filteredProduct.image} />
</div>
)
}
Now the filteredProduct
variable has the data for either A or G, and you can use it to display the specific data you want, inside the Payment component.
Upvotes: 1