0

I want to pass data from a component to another page in React, the component named Country.js has the data I fetched in my app component from an API as a prop, I used react router to create the second page named Details.js

I used the useLocation hook it didn't work for me, the data is valid in the country.js component but it becomes null when it's passed to my Details.js page. what should I do?

country.js (the component i want to pass data from)
import React from 'react'
import { Link } from 'react-router-dom'

function Country(props) {
  const {data,img, cap, reg, alt, name, pop} = props
  return (
    <Link to={{
      pathname: '/details',
      state: { data }
    }}>
       <div className='w-72 h-80 shadow bg-white rounded-sm mx-auto cursor-pointer'>
      <img className='w-full h-1/2 rounded-sm' src={img} alt={alt}
      />
      <div className='pt-3 pl-4'>
      <h3 className='font-extrabold pb-2 pt-1 text-darkBlue'>{name}</h3>
      <p className='text-sm text-darkBlue font-bold'>population:
      <span className='text-lightDarkGray font-normal' >{pop}</span></p>
      <p className='text-sm text-darkBlue font-bold'>region:
      <span className='text-lightDarkGray font-normal'>{reg}</span></p>
      <p className='text-sm text-darkBlue font-bold'>capital:
      <span className='text-lightDarkGray font-normal'>{cap}</span></p>
      </div>
    </div>
    </Link>
  )
}

export default Country

Details.js (the page i want to receive data from)

import React from 'react'
import Navbar from './components/Navbar'
import { useLocation } from 'react-router-dom'



function Details() {
  const location = useLocation();
  const { data } = location.state;
  return (
    <>
    <Navbar/>
    <h1>Details</h1>
      {data ? (
        <div>
          <h2>{data.name}</h2>
          <p>Population: {data.population}</p>
        </div>
      ) : (
        <p>Country not found</p>
      )}
    </>
  )  
}

export default Details

main.js(my index page)
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
import {createBrowserRouter,RouterProvider,Route} from 'react-router-dom'
import Details from './Details'
const router = createBrowserRouter([
  {
    path: "/",
    element: <App/>,
  },
  {
    path:"/details",
    element:<Details/>
  }
]);
ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
)


App.js (where i fetched the data)
import React from 'react'
import { useState, useEffect } from 
'react'
import Navbar from './components/Navbar.jsx'
import Search from './components/Search.jsx'
import Country from './components/Country.jsx'



function App() {
  const [data, setData] = useState([]);
  const [loadMore, setLoadMore] = useState(20)
  const [isDataMax, setIsDataMax] = useState(false)
  
  useEffect(() => {
    async function fetchData() {
      const response = await fetch('https://restcountries.com/v3.1/all');
      const json = await response.json();
      setData(json);
    }
    fetchData();
  }, []);
  
  let onePageData = data.slice(0, loadMore)
  const load = ()=> {
    setLoadMore(loadMore + 20)
    if(loadMore == 240) {
      setIsDataMax(true)
    }
  }
  return (
    <>
    <main className="main bg-veryLightGray w-full h-full mx-auto">
        <Navbar/>
        <Search/>
        <article className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 items-center justify-stretch lg:w-128 gap-6 mx-auto'>
         {onePageData? 
         onePageData.map((country,index) => 
         <Country data={country} alt={onePageData[index].flags.alt} reg={country.continents} name={country.name.common} pop={country.population} cap={country.capital} img={onePageData[index].flags.png}/>):
         <p className='mx-auto text-10 font-bold'>Loading countries...</p>
         }
        </article>
        { !isDataMax && <button className='block mx-auto bg-darkBlue text-white px-4 py-2 font-bold rounded-lg mb-5
        ' onClick={load}>Load More</button>}
    </main>
    </>
  )
}

export default App


1 Answer 1

0

Try to get your data directly in a hook function useCountry() for example and call it from Detail page. You can also put params such as country_code : useCountry('en') for 'en' as country_code.

1
  • thank you! i used useNavigate() instead of link and it finally worked!
    – Ma Nar
    Commented May 27, 2023 at 12:19

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.