Home > front end >  How to do multiple fetch data and conditional render in react
How to do multiple fetch data and conditional render in react

Time:09-23

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.

  • Related