0

I have a Context API file setup which has a state and a function which fetches data from an API and sets the state, and i want to pass the state down to my other components. In my App.js, I am using React-Router to specify the routes. How do i pass the state down to these components using Context API, whilst using React-Router.

My ApiContext.js file looks like this :

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

export const ApiContext = createContext();

export const ApiProvider = async (props) => {
    const [data, setData] = useState(null);

    const getURL = 'https://examplefetchsite.com';
    const response = await fetch(getURL).json();
    setData(response);
    return (
        <ApiContext.Provider value={[data, setData]}>
            {props.children}
        </ApiContext.Provider>
    );
}

My App.js's return looks like this :

return (
      <ApiProvider>
        <Router>
          <div>
            <NavBar />
            <Switch>
            <Route path="/" exact component={ Dashboard } />
            <Route path="/create" component={ Create } />
            <Route path="/view" component={View} />
            </Switch>
          </div>
        </Router>
      </ApiProvider>
    )

2 Answers 2

2

In terms of the context itself, you don't have to change anything in your provider and only do something like this in the child components:

import React, {useContext} from 'react'
import {ApiContext} from './ApiContext'

const Dashboard = (props) => {
    const [data, setData] = useContext(ApiContext)

    //you should have access to both data and setData

    return (
        //things
    )
}

However in the ApiContext.js you aren't calling the API request properly. You should use useEffect to fetch the data only on the first render.

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

export const ApiContext = createContext();

export const ApiProvider = (props) => {
    const [data, setData] = useState(null);

    useEffect(async () => {
        const getURL = 'https://examplefetchsite.com';
        const response = await fetch(getURL).json();
        setData(response);
    }, [])

    return (
        <ApiContext.Provider value={[data, setData]}>
            {props.children}
        </ApiContext.Provider>
    );
}
Sign up to request clarification or add additional context in comments.

6 Comments

I am currently doing this, but React throws this error "Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead."
Nope, I tried useEffect() and that doesn't seem to solve it. I am still getting the error that i mentioned above.
Did you try my code? You had an async in the ApiProvider, which would attempt to create an asynchronous component, which is impossible
Thank you so much man ! I realised that the problem was on the async, it worked once i removed the async , stupid me! Thank you !
Will this cause a re-render if the context changes?
|
0

ApiProvider

<ApiContext.Provider value={{data, setData}}>

Child component

const context = useContext(ApiContext); 
console.log(context.data); 
context.setData(123);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.