I'm trying to improve my state management skill so I chose to use REACT CONTEXT. I am getting item data from my backend server using axios and storing it in the context.
When I am in /home
everything works properly: state updates then component rerenders and everything looks ok. But when I move to /shop
and I console.log(items)
it returns me an empty array instead of data that I got just before.
Here are my files:
APP.JS
import logo from './logo.svg';
import './App.css';
import Nav from './components/navigations/NavBAr/Nav';
import HeaderSlides from './components/slides/header/HeaderSlide';
import Home from './components/Home/Home';
import Footer from './components/footer/Footer';
import { Route, Switch } from 'react-router-dom';
import Login from './components/Logs/Login/Login';
import { useState } from 'react';
import { ItemProvider } from './context/ItemContext';
import Register from './components/Logs/Register/Register';
import { UserProvider } from './context/UserContext';
import Shop from './components/Shop/Shop';
function App() {
return (
<ItemProvider>
<UserProvider>
<div className="App">
<header>
<Nav/>
</header>
<Route render={({ location }) => (
<Switch location={location}>
<Route exact path='/' render={ () => (<Home/>)}/>
<Route path='/login' component={Login}/>
<Route path='/register' component={Register}/>
<Route path='/shop' component={Shop}/>
</Switch>
)} />
<footer>
<Footer/>
</footer>
</div>
</UserProvider>
</ItemProvider>
);
}
export default App;
ItemContext
import axios from 'axios';
import React, { useState, createContext, useEffect } from 'react';
export const ItemContext = createContext();
export function ItemProvider(props) {
const [items, setItems] = useState([]);
return (
<ItemContext.Provider value={[items, setItems]}>
{props.children}
</ItemContext.Provider>
);
}
**Item.js ** call in Home.js context work
import React, { useContext, useEffect } from 'react';
//styles
import './Items.css'
//items
import { ItemContext } from '../../../../context/ItemContext'
export default function Items({ toShow }) {
const [items, setItems] = useContext(ItemContext);
const data = items
let stuff;
if (data.length === 0) {
console.log("loading");
} else {
console.log(data);
stuff = data.map((details, i) => {
const { name, brand, gender, price, image, categorie } = details;
while (gender === toShow) {
return (
<div id="itemCard1">
<div className="itemImgWrap">
<img src={image} alt="first image" />
</div>
<div className="details">
<p className="detailsName">{name}</p>
<p className="brand">{brand} </p>
<p className="gender">{gender}</p>
<p className="price">{price}€</p>
</div>
</div>
)
}
})
}
return (
<div className="productItem">
{stuff}
</div>
)
}
Views.js call in Shop.js context doesn't work
import React, { useContext, useEffect, useState } from 'react';
import './Views.css'
//items
import { ItemContext } from '../../../context/ItemContext'
export default function Views() {
const [items, setItems] = useContext(ItemContext);
console.log(items);
const data = items
let stuff;
if (data.length === 0) {
console.log("nothing");
} else {
console.log(data);
stuff = data.map((details, i) => {
const { name, brand, gender, price, image, categorie } = details;
return (
<div id="itemCard1">
<div className="itemImgWrap">
<img src={image} alt="first image" />
</div>
<div className="details">
<p className="detailsName">{name}</p>
<p className="brand">{brand} </p>
<p className="gender">{gender}</p>
<p className="price">{price}€</p>
</div>
</div>
)
})
}
return (
<div className="viewsContainer">
<div className="viewsGrid">
{stuff}
</div>
</div>
)
}
So i solved it by using react-router-dom <Link/>
.
Given that I wanted to do the routes once my pages are initialized,
I was navigating between pages by url, so Context was always clearing and app refreshing witch is not what we want. So I used <Link/>
and then it works because <Link/>
help you to navigate without refreshing I guess...