Tequila
Tequila

Reputation: 256

Passing data from json via React Router

Hello Stackoverflow Community. So I have a problem with passing data from one Component to another. So I have Free To Play Component which is taking freetoplay data from json and rendering it on display. I have also a Link which should open up a Payment Route and pass the data. In the Payment I have a filter function, which is fitering based on id. Anyway when I press on the Link, it should render the image class and price, but it does not, I dont know why. Dont get confused by Context it is just Search functionality. I have posted this question numerous times, but nobody seems to give me the answer , and why is it happening. And could I use Redux to achieve this functionality. If anyone could help me I would be very grateful. Cheers

import React from 'react'
import { useLocation } from "react-router-dom";
import data from "../data.json";

function Payment() {  
 const { state: { product } } = useLocation();
    return (
        <div  className='Payment'>
         <img src={product.image}></img>
         <h1>{product.price}</h1>
         <h1>{product.name}</h1>          
        </div>
    )
}

export default Payment


import React from 'react'
import data from "./data.json";
import {
    
    Link
  } from "react-router-dom";
import { SearchContext } from './SearchContext';


function FreeToPlay() {
  const {filterProduct}=React.useContext(SearchContext);
    return (
        <>
          <div className='All' >
            {data[0].freetoplay.filter(filterProduct).map((product) => {
              return (
                <div className='f2p' key={product.id}>               
                    <img src={product.image}></img>
                    <h2>{product.name}</h2>
                    <h5>{product.price}</h5>
               <Link  className='link'  to={{
    pathname: `/payment/${product.id}`,
    state: {
      product, 
    },
  }}>
        </div>
              );
            })}
          </div>
        </>
      );
}

export default FreeToPlay

json
[
  {
    "freetoplay": [{
        "id": "0",
        "image": "src=fsdf",
        "price": "60$",
        "name": "CS Go"
      },
      {
        "id": "1",
        "image": "src=fsdf",
        "price": "6$",
        "name": "Fifa"
      }
    ],
 
    "action": [{
        "id": "2",
        "image": "src=fsdf",
        "price": "60$",
        "name": "doom"
      },
      {
        "id": "3",
        "image": "src=fsdf",
        "price": "66$",
        "name": "cyberpunk"
      }
    ],
    
  }
]

import React, { useState, useContext } from 'react';

export const SearchContext =React.createContext(null)
export  default function SearchProvider({children}) {

const [searchValue, setSearchValue] = React.useState("");


function filterProduct(product) {
     return product.name.toLowerCase().includes(searchValue.toLowerCase());
     }
      return( 

       <SearchContext.Provider value ={{filterProduct,   searchValue, 
        setSearchValue}}>
             {children} 
        </SearchContext.Provider>             
             ); }


function Routes() {
    return (
       
        <div>     
          <Router>                 
            <SideBar /> 
          <Switch>   
           <Route  path="/payment/:productId">
             <Payment/>
           </Route>             
           <Route path="/freetoplay">  
            <FreeToPlay  />
           </Route>  
            <Route path="/action">  
              <Action  />
            </Route>           
            </Switch>  
          </Router>
       </div>
    )
}

export default Routes

Upvotes: 3

Views: 3269

Answers (2)

kishore.jannarapu
kishore.jannarapu

Reputation: 79

In React router V6, you can use below.

Docs: https://reactrouter.com/en/main/components/link#state

The state property can be used to set a stateful value for the new location which is stored inside history state. This value can subsequently be accessed via useLocation().

<Link to="new-path" state={{ some: "value" }} />

You can access this state value while on the "new-path" route:

let { state } = useLocation();

Upvotes: 0

Drew Reese
Drew Reese

Reputation: 202618

You can try using route state to send the product object with the route transition.

<Link
  to={{
    pathname: `/payment/${product.id}`,
    state: {
      product, // <-- the mapped product from data
    },
  }}
  className='link'
>
  Buy Now
</Link>

On the component being rendered on the receiving route you can access the state from the location object.

Via props (this.props or props if a functional component). Can either be directly rendered by a Route or wrapped with the withRouter Higher Order Component.

const { state: { product } } = props.location;

Via useLocation react hook.

const { state: { product } } = useLocation();

Upvotes: 5

Related Questions