Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass route params in Context API

I'm using the context API and I have this in my context file:

useEffect(() => {
    async function getSingleCountryData() {
      const result = await axios(
        `https://restcountries.eu/rest/v2/alpha/${props.match.alpha3Code.toLowerCase()}`
      );
      console.log(result)
      setCountry(result.data);
    }
    if (props.match) getSingleCountryData();
  }, [props.match]);

In the component I'm using, it doesn't work because it doesn't know what the props.match.alpha3Code is. How can I can pass the value? The alpha3Code is coming from the URL: localhost:3000/country/asa where asa is the alpha3Code, how can I get this value?

Basically, what I'm trying to do is. I have a list of countries I listed out on the home page. Now I'm trying to get more information about a single country. The route is /country/:alpha3Code where alpha3Code is gotten from the API.

FWIW, here is my full context file:

import React, { useState, createContext, useEffect } from 'react';
import axios from 'axios';

export const CountryContext = createContext();

export default function CountryContextProvider(props) {
  const [countries, setCountries] = useState([]);
  const [country, setCountry] = useState([]);

  useEffect(() => {
    const getCountryData = async () => {
      const result = await axios.get(
        'https://cors-anywhere.herokuapp.com/https://restcountries.eu/rest/v2/all'
      );
      setCountries(result.data);
    };
    getCountryData();
  }, []);

  useEffect(() => {
    async function getSingleCountryData() {
      const result = await axios(
        `https://restcountries.eu/rest/v2/alpha/${props.match.alpha3Code.toLowerCase()}`
      );
      console.log(result)
      setCountry(result.data);
    }
    if (props.match) getSingleCountryData();
  }, [props.match]);

  return (
    <CountryContext.Provider value={{ countries, country }}>
      {props.children}
    </CountryContext.Provider>
  );
}

In the component I'm using the country, I have: const { country } = useContext(CountryContext);

I know I can do this from the component itself, but I'm learning how to use the context API, so I'm handling all API calls in my context.

The API I'm making use of is here

Codesandbox Link

Project Github link

like image 640
Peoray Avatar asked Oct 23 '25 15:10

Peoray


1 Answers

You can update the context from a component using it by passing down a setter function which updates the context state.

export default function CountryContextProvider({ children }) {
  const [countries, setCountries] = useState([]);
  const [country, setCountry] = useState([]);
  const [path, setPath] = useState('');

  useEffect(() => {
    async function getSingleCountryData() {
      const result = await axios(`your/request/for/${path}`);
      setCountry(result.data);
    }
    if(path) getSingleCountryData();
  }, [path]);

  return (
    <CountryContext.Provider value={{ countries, country, setPath }}>
      {children}
    </CountryContext.Provider>
  );
}

Now use setPath to update the request endpoint with the route match once this component is mounted.

const Details = ({ match }) => {
  const {
    params: { alpha3Code }
  } = match;
  const { country, setPath } = useContext(CountryContext);

  useEffect(() => {
    setPath(alpha3Code);
  }, [alpha3Code]);

  return (
   <main>Some JSX here</main>
  );
};

export default withRouter(Details);

Linked is a working codesandbox implementation

like image 145
Joseph Rex Avatar answered Oct 25 '25 03:10

Joseph Rex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!