https://www.npmjs.com/package/react-loading-skeleton
react-loading-skeleton
Make beautiful, animated loading skeletons that automatically adapt to your app.. Latest version: 3.3.1, last published: 7 months ago. Start using react-loading-skeleton in your project by running `npm i react-loading-skeleton`. There are 499 other project
www.npmjs.com
npm install react-loading-skeleton

import Skeleton from "react-loading-skeleton";
import "react-loading-skeleton/dist/skeleton.css";
const ProductCardSkeleton = () => {
return <Skeleton className="product_card" width="275px" />;
};
export default ProductCardSkeleton;
ProductsList.jsx
error์ data ๋ฐ๋ณต๋ฌธ ์ฌ์ด์ ์์น
{error && <em className='form_error'>{error}</em>}
<ProductCardSkeleton />
{data.products &&
data.products.map((product) => (

1~8๊น์ง์ ์ซ์๋ฅผ ๋ฐฐ์ด๋ก ๋ง๋ค์ด์ ์ค์ผ๋ ํค์ ๋ฐ๋ณตํ๋ค.
import useData from "../../Hook/useData";
import ProductCard from "./ProductCard";
import ProductCardSkeleton from "./ProductCardSkeleton";
import "./ProductsList.css";
const ProductsList = () => {
//useDate(url)์ด ๋ค์ด๊ฐ์ผํจ
//๊ฒฐ๊ณผ(res)๋ categories์, error์ ๋ด๋๋ค.
const { data, error } = useData("/products");
const skeletons = [1, 2, 3, 4, 5, 6, 7, 8];
return (
<section className="products_list_section">
<header className="align_center products_list_header">
<h2>์ํ๋ชฉ๋ก</h2>
<select name="sort" id="" className="products_sorting">
<option value="">์ ๋ ฌ๋ฐฉ๋ฒ</option>
<option value="price desc">๊ฐ๊ฒฉ๋์์</option>
<option value="price asc">๊ฐ๊ฒฉ๋ฎ์์</option>
<option value="rate desc">ํ์ ๋์์</option>
<option value="rate asc">ํ์ ๋ฎ์์</option>
</select>
</header>
<div className="products_list">
{/* ์๋ฌ๊ฐ ์์ ๊ฒฝ์ฐ ์๋ฌ ํ์ */}
{error && <em className="form_error">{error}</em>}
{skeletons.map((n) => (
<ProductCardSkeleton key={n} />
))}
{/* products๊ฐ ์์ ๊ฒฝ์ฐ ๋ฐ๋ณต๋ฌธ์ผ๋ก ์ถ๋ ฅ */}
{data.products &&
data.products.map((product) => (
<ProductCard
key={product._id}
id={product._id}
title={product.title}
image={product.images[0]}
price={product.price}
rating={product.reviews.rate}
ratingCounts={product.reviews.counts}
stock={product.stock}
/>
))}
</div>
</section>
);
};
export default ProductsList;

Hook -> useData.js์ ๋ก๋ฉ์ ์ถ๊ฐํ๋ค.
import { useEffect, useState } from "react";
import apiClient from "../utils/api-client";
const useData = (url) => {
const [data, setData] = useState([]);
const [error, setError] = useState("");
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
apiClient
.get(url)
.then((res) => {
setData(res.data);
setIsLoading(false);
})
.catch((err) => {
setError(err.message);
setIsLoading(false);
});
}, []);
return { data, error, isLoading };
};
export default useData;
๊ทธ๋ฆฌ๊ณ ProductsList.jsx์์ ๋ก๋ฉ ๊ฐ์ ธ์จ๋ค
const { data, error, isLoading } = useData("/products");
{isLoading && skeletons.map((n) => <ProductCardSkeleton key={n} />)}
๋ก๋ฉ ์ผ ๊ฒฝ์ฐ์ ์ค์ผ๋ ํค์ ๋ณด์ฌ์ค๋ค.

์๋ ๋นจ๋ผ์ ์์๋ณด์
'FRONTEND > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [myCart] ํ์ด์ง๋ค์ด์ (0) | 2023.12.20 |
|---|---|
| [myCart] ์นดํ ๊ณ ๋ฆฌ ๋ณ ์ํ ์ถ๋ ฅ (0) | 2023.12.20 |
| [myCart] ์ปค์คํ Hook ์์ฑ ํ ์ ์ฉ (0) | 2023.12.20 |
| [myCart] ๋ฆฌ์กํธ ๋ผ์ฐํฐ ์ ์ฉ / axios์ค์น ํ ๋ฐฑ์๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ (0) | 2023.12.20 |
| [myCart] ๋ชฝ๊ณ DB /๋ฐฑ์๋ ์คํ (0) | 2023.12.20 |