skip to Main Content

I am new to react and I am a little bit lost with createContext hook.

I created a Api component to fetch data from my backend

export interface List{
    id?: string,
    sku?: string,
    name?: string,
    description?: string,
    unit_price?: number,
    image_url?: string,
    active?: boolean,
    units_in_stock?: number,
    date_created?: Date,
    last_updated?: Date,
    category?:number
}
export const Context = createContext<List[]>([])
 function Api() {

    const [product, setProduct] = useState<List[]>([])

    useEffect(() => {
      const fetchData = async ()=>{

        try {
            const response = await axios.get('http://127.0.0.1:8000/djassa/products/')
            setProduct(response.data)
            
            
        } 
        
        catch (error) {
            console.error("Failed to fetch products", error)     
        }
      }

      fetchData()
    }, [])
    

  return (
    <>
        < Context.Provider value={product} >
            <Home />
        </Context.Provider>

    </>
  )
}

export default Api

Then I wanted to display some of the data into Home Component.

function Home(){

    const data = useContext(Context)
   console.log(data);
   
    

    return(   
         <>
        {data.map((product) => (
          <p key={product.id}>{product.name}</p> 
        ))}
        <p>You just entered home.</p>
      </>)
}

export default Home

The problem is when I tried to rend home, it does not work

import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css'
import Home from './assets/component/Home';
import Api from './assets/component/Api';



function App() {

  return (
    <>
      <Home />

    </>
  )
}

export default App

However, when I add Api component in place of Home component in my App component. it seams to work.

import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css'
import Home from './assets/component/Home';
import Api from './assets/component/Api';



function App() {

  return (
    <>
      <Api />

    </>
  )
}

export default App

2

Answers


  1. When you render Home component alone there is not any Context context provider being rendered above it in the ReactTree so the default context value is accessed, e.g. the empty array.

    function App() {
      return (
        <>
          <Home /> // ??? where's the context? 🤷🏻‍♂️
        </>
      )
    }
    

    In the second example where you instead render Api, this works because Home is rendered as a direct child of the Context.Provider component and can thus access the provided context value.

    function App() {
      return (
        <>
          <Api /> // <-- renders the context provider
        </>
      )
    }
    
    function Api() {
      ...
        
    
      return (
        <Context.Provider value={product}> // <-- provides the context
          <Home /> // <-- can access context 🙂
        </Context.Provider>
      );
    }
    

    A common pattern for context providers is to wrap and render their children prop.

    Example:

    function Api({ children }) {
      ...
        
    
      return (
        <Context.Provider value={product}>
          {children}
        </Context.Provider>
      );
    }
    

    Which allows you to render context consumers elsewhere in the sub-ReactTree.

    function App() {
      return (
        <Api>
          ...
          <Home />
          ...
        </Api>
      );
    }
    
    Login or Signup to reply.
  2. Don’t forget to supply the context for the <Home /> component –

    function App() {
      return (
        <Context.Provider value={...}>
          <Home />
        </Context.Provider>
      )
    }
    

    new for React 19

    In React 19, you can render <Context> as a provider instead of <Context.Provider>

    function App() {
      return (
        <Context value={...}>
          <Home />
        </Context>
      )
    }
    

    New context providers can use <Context> and React team will be publishing a codemod to convert existing providers. In future versions <Context.Provider> will be deprecated.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search