Kevin
Kevin

Reputation: 187

How to pass a function as value in React Context when using Typescript?

I am trying to use createContext in my typescript application and struggling to initialise all of the values I want to pass through my provider:

I eventually want to pass a set of values through my context:

To start I have declared the interface necessary to declare my context:

interface ContextParametersType {

  greenValue: { greenStatus: Set<EnumType>, setGreenStatus: Dispatch<SetStateAction<Set<EnumType>>> };
  redValue: { redStatus: Set<EnumType>, setRedStatus: Dispatch<SetStateAction<Set<EnumType>>> };
  searchValue: { searchTerm: string, setSearchTerm: Dispatch<SetStateAction<string>> }
  getResults: () => void

}

Then my next step is to initialise all these values, it is here where I am stuck on how to initalise the async function that will return an api GET request.

const StateContext = createContext<ContextParametersType>({

  greenValue: {
    greenStatus: new Set<EnumType>(), setGreenStatus: () => {
    }
  },
  redValue: {
    redStatus: new Set<EnumType>(), setRedStatus: () => {
    }
  },
  searchValue: {
    searchTerm: '', setSearchTerm: () => {
    }
  },

  // getResults?:{ () => void} <------ How to initalise here?

})

Then I wish to pass these context values down into my provider like so:

export const StateContextProvider = ({ children }: Props) => {
   
  const [results, setResults] =
    useState<Array<EnumType>>();

  const [greenStatus, setGreenStatus] =
    useState(new Set<EnumType>());
  const [redStatus, setRedStatus] =
    useState(new Set<EnumType>());
  const [searchTerm, setSearchTerm] = useState<string>('')


  const greenValue = { greenStatus, setGreenStatus };
  const redValue = { redStatus, setRedStatus };
  const searchValue = { searchTerm, setSearchTerm };


    const getResults = async () => {
      const axios = require("axios");

      const options = {
        method: 'GET',
        url: 'https://google-search72.p.rapidapi.com/search',
        params: {query: 'rapidapi', gl: 'us', lr: 'en', num: '10', start: '1'},
        headers: {
          'X-RapidAPI-Key': 'SIGN-UP-FOR-KEY',
          'X-RapidAPI-Host': 'google-search72.p.rapidapi.com'
        }
      };
      
      axios.request(options).then(function (response: { data: any; }) {
        console.log(response.data);
      }).catch(function (error: any) {
        console.error(error);
      });

    };


  return (

    <StateContext.Provider value={{ greenValue, redValue, searchValue }}>
      {children}
    </StateContext.Provider>
  );
};

How do I initalise the getResults function in Typescript when creating the context from the interface?

Thanks

Upvotes: 0

Views: 1006

Answers (1)

Aifos Si Prahs
Aifos Si Prahs

Reputation: 363

interface ContextParametersType {

  greenValue: { greenStatus: Set<EnumType>, setGreenStatus: Dispatch<SetStateAction<Set<EnumType>>> };
  redValue: { redStatus: Set<EnumType>, setRedStatus: Dispatch<SetStateAction<Set<EnumType>>> };
  searchValue: { searchTerm: string, setSearchTerm: Dispatch<SetStateAction<string>> }
  getResults: () => Promise<void>

}

1 - For any async function, the return type should be a promise.

2 - If you need to define its default value, it can be just an empty async function like.

const StateContext = createContext<ContextParametersType>({

  greenValue: {
    greenStatus: new Set<EnumType>(), setGreenStatus: () => {
    }
  },
  redValue: {
    redStatus: new Set<EnumType>(), setRedStatus: () => {
    }
  },
  searchValue: {
    searchTerm: '', setSearchTerm: () => {
    }
  },

  getResults: async () => void
})

Then when you want to pass the real function in, you can do it like this:

export const StateContextProvider = ({ children }: Props) => {
   
  const [results, setResults] =
    useState<Array<EnumType>>();

  const [greenStatus, setGreenStatus] =
    useState(new Set<EnumType>());
  const [redStatus, setRedStatus] =
    useState(new Set<EnumType>());
  const [searchTerm, setSearchTerm] = useState<string>('')


  const greenValue = { greenStatus, setGreenStatus };
  const redValue = { redStatus, setRedStatus };
  const searchValue = { searchTerm, setSearchTerm };


    const getResults = async () => {
      const axios = require("axios");

      const options = {
        method: 'GET',
        url: 'https://google-search72.p.rapidapi.com/search',
        params: {query: 'rapidapi', gl: 'us', lr: 'en', num: '10', start: '1'},
        headers: {
          'X-RapidAPI-Key': 'SIGN-UP-FOR-KEY',
          'X-RapidAPI-Host': 'google-search72.p.rapidapi.com'
        }
      };
      
      axios.request(options).then(function (response: { data: any; }) {
        console.log(response.data);
      }).catch(function (error: any) {
        console.error(error);
      });

    };


  return (

    <StateContext.Provider value={{ getResults, greenValue, redValue, searchValue }}>
      {children}
    </StateContext.Provider>
  );
};

Upvotes: 0

Related Questions