I'm building MERN stack app wherein when logged in as Admin it will render all products in a table and when logged in as Not Admin it will render active products in cards.
I'm trying to do multiple fetch data in my Products.js page
//Products.js
import { Fragment, useEffect, useState, useContext } from "react";
import { Container, Table } from "react-bootstrap";
import ProductCard from "../components/ProductCard";
import UserContext from "../UserContext";
export default function Products() {
const { user } = useContext(UserContext);
const [userProducts, setUserProducts] = useState([]);
const [adminProducts, setAdminProducts] = useState([]);
// FETCH DATA
useEffect(() => {
fetchAdminProducts();
}, []);
useEffect(() => {
fetchUserProducts();
}, []);
const fetchAdminProducts = () => {
fetch("http://localhost:4000/products/all")
.then((res) => res.json())
.then((data) => {
setAdminProducts(data);
});
};
const fetchUserProducts = () => {
fetch("http://localhost:4000/products/")
.then((res) => res.json())
.then((data) => {
setUserProducts(data);
});
};
return (
<Fragment>
<Container>
{user.isAdmin === true ?
(...) :
(...)}
</Container>
</Fragment>
);
}
Am I doing it correctly?
How do I map Admin products in a table and User products in a card?
What is the best approach to fetch multiple data and render it conditionally when logged in?
Thanks for the help guys!
CodePudding user response:
try to check the user role inside the useEffect
//Products.js
import { Fragment, useEffect, useState, useContext } from "react";
import { Container, Table } from "react-bootstrap";
import ProductCard from "../components/ProductCard";
import UserContext from "../UserContext";
export default function Products() {
const { user } = useContext(UserContext);
const [userProducts, setUserProducts] = useState([]);
const [adminProducts, setAdminProducts] = useState([]);
// FETCH DATA
useEffect(() => {
if(user.isAdmin){ // <-- check if is Admin
fetchAdminProducts();
} else{
fetchUserProducts();
}
}, []);
const fetchAdminProducts = () => {
fetch("http://localhost:4000/products/all")
.then((res) => res.json())
.then((data) => {
setProducts(data);
});
};
const fetchUserProducts = () => {
fetch("http://localhost:4000/products/")
.then((res) => res.json())
.then((data) => {
setProducts(data);
});
};
return (
<Fragment>
<Container>
{user.isAdmin === true ?
(...) :
(...)}
</Container>
</Fragment>
);
}
CodePudding user response:
I would recommend having one function rather than 2 and also have like a state that will make that your useEffect go off.
const [state,setState]=useState(null);
const [products,setProducts]=useState([]);
const fetchProducts = () => {
if(user ==="Admin"){
fetch("http://localhost:4000/products/all")
.then((res) => res.json())
.then((data) => {
setProducts(data);
});
setState(true);
}
else{
fetch("http://localhost:4000/products/")
.then((res) => res.json())
.then((data) => {
setProducts(data);
});
setState(false);
}
};
usEffect(()=>{
fetchProducts();
},[state])
Then the return would look like that.
return (
{state ? <Table data=products> : <Card data=products>}
)
Would recommend create a seperate component that you call Table and Card that take in products. This will make your code more neat and easier to manage.
Hope this help.