ما با چالش ساخت یک گالری تصاویر با اسکرول بی نهایت رو به رو هستیم. در این پست، ما این چالش را با استفاده از React.js، یک کتابخانه frontend معروف برای JavaScript، و همچنین CSS Grid برطرف خواهیم کرد.
جدول محتوا:
- چالش پیش رو
- راه حل
- نتیجه گیری
چالش پیش رو
از ما خواسته شده است که یک گالری تصاویر را با استفاده از یک پایه Codepen که برای ما فراهم شده است و شامل HTML پایه برای ذخیرهسازی استایلبندی تصاویر میباشد، بسازیم. همچنین یک اندپوینت API بری دریافت تصاویر تصادفی هم برای ما فراهم شده است. شما میتوانید کد مذکور را در این لینک بیابید.
راه حل
برای برطرف کردن این چالش، ما از React.js برای ساخت یک رابط استفاده میکنیم، از Axios برای ارسال درخواستهای HTTP بهره میبریم و از کتابخانه react-infinite-scroll هم برای پیادهسازی ویژگی اسکرول بینهایت استفاده میکنیم. ما این کارها را در ۵ قدم انجام خواهیم داد:
۱. نصب تمام پکیجهای مورد نیاز
۲. ساخت کامپوننت مربوط به ذخیرهسازی تصاویر
۳. ساخت یک کامپوننت تصویر ساده
۴. دریافت تصاویر تصادفی از Unspplash و رندر کردن آنها
۵. استایلبندی گالری
همچنین برای این چالش، ما React Hooks که در نسخه 16.8 منتشر شدهاند را به کار خواهیم برد، و به این صورت از کامپوننتهای تابعی در پروژه خود استفاده خواهیم کرد.
پکیجهای مورد نیاز را نصب کنید
تمام dependencyهای مورد نیاز را از یک CDN وارد کنید. Codepen یک نوار جستجو را فراهم میکند که در آن میتوانید نام ماژول مورد نظر را وارد کرده، از میان آن را نتایج انتخاب کنید و سپس Codepen آن را به پروژه شما اضافه خواهد کرد. Dependencyهای نصب شده عبارتند از:
- React
- React-DOM
- React-Infinite-Scroll-Component
- Axios
به Unsplash بروید تا یک برنامه جدید بسازید و یک کلید دسترسی بگیرید.
کامپوننت پایه را بسازید
در React، قالب HTML مربوط به کامپوننت والد در JSX نوشته میشود. ما با نوشتن این عناصر HTML که قالب مورد نظر را در JSX میسازند، ادامه خواهیم داد. با استفاده از این کد، یک کامپوننت تابعی بسازید و آن را بر روی DOM رندر کنید:
let Collage = () => {
// Return JSX
return (
<div className="hero is-fullheight is-bold is-info">
<div className="hero-body">
<div className="container">
<div className="header content">
<h2 className="subtitle is-6">Code Challenge #16</h2>
<h1 className="title is-1">
Infinite Scroll Unsplash Code Challenge
</h1>
</div>
// Images go here
</div>
</div>
</div>
);
};
// Render the component to the DOM element with ID of root
ReactDOM.render(<Collage />, document.getElementById("root"));
در اینجا، شما به سادگی کامپوننت والد Collage را میسازید، عناصر HTML را در JSX بر میگردانید و آن را با آیدی root در عنصر DOM رندر میکنید. در اینجا کلاسهای Bulma برای فراهم کردن استایلبندی پایه برای صفحه مورد استفاده قرار گرفته است.
یک کامپوننت تصویر بسازید
ما ادامه میدهیم تا یک کامپوننت را برای یک تصویر که دریافت شده است، بسازیم. این کار به ما در تعیین موقعیت هر تصویر کمک خواهد کرد. با استفاده از این کد، یک کامپوننت تابعی بسازید:
const UnsplashImage = ({ url, key }) => (
<div className="image-item" key={key} >
<img src={url} />
</div>
);
این کامپوننت propهای url و key که در واقع به ترتیب url تصویری که قرار است نمایش داده شود، و کلید هر تصویر رندر شده میباشند را دریافت میکند. ما از عنصر <img/> برای نمایش تصویر دریافت شده داخل کامپوننت استفاده میکنیم.
تصاویر تصادفی را از Unsplash دریافت کنید و آنها را رندر کنید
Unsplash یک API رایگان برای دریافت تصاویر تصادفی فراهم میکند، که ما از آنها استفاده خواهیم کرد. تصاویر در یک محفظه state ذخیره شده، و از state به DOM منتقل خواهند شد. از آنجایی که ما در حال استفاده از React Hooks هستیم، state و متدهای lifecycle را به ترتیب با استفاده از useState و useEffect مدیریت خواهیم کرد. در کامپوننت Collage، دو متغیر state بسازید. یکی برای نگه داشتن تصاویر ورودی و دیگری برای ذخیره یک boolean، درباره این که آیا تصویر مورد نظر بارگذاری شده است یا نه.
[...]
const [images, setImages] = React.useState([]);
const [loaded, setIsLoaded] = React.useState(false);
[...]
سپس ما یک تابع خواهیم ساخت که ۱۰ تصویر تصادفی را با استفاده از Axios دریافت میکند. این کار با ارسال یک درخواست GET به اندپوینت API، در حین منتقل کردن کلید دسترسی خود و مقدار تصاویری که میخواهید دریافت کنید انجام میشود. این کار را با استفاده از این کد انجام دهید:
const fetchImages = (count = 10) => {
const apiRoot = "https://api.unsplash.com";
const accessKey = "{input access key here}";
axios
.get(`${apiRoot}/photos/random?client_id=${accessKey}&count=${count}`)
.then (res => {
setImages([...images, ...res.data]);
setIsLoaded(true);
});
};
Axios یک کتابخانه بر پایه promise است و ما در هنگام نتیجهدهی درخواست، از متد setImages برای پر کردن تصاویر دریافت شده و همچنین پخش کردن تصاویری که از پیش دریافت شدهاند، استفاده میکنیم. همچنین، مقدار loaded را برابر با true قرار میدهیم.
حال که ما تصاویر را در state ذخیره کردهایم، بیایید وقتی که کامپوننت مورد نظر سوار شده است (mount شده است)، تابع fetchImages را فراخوانی کنیم. پیشتر ما این کار را با استفاده از متد lifecycle با نام componentDidMount انجام میدادیم. گرچه، React هوک useEffect را برای مدیریت کردن عملیاتهای lifecycle در یک کامپوننت تابعی فراهم میکند. در کامپوننت Collage و در هنگام سوار شدن، متد fetchImage را با استفاده از این کد فراخوانی کنید:
[...]
React.useEffect(() => {
fetchImages();
}, []);
[...]
هوک useEffect یک پارامتر دوم که یک آرایه است را میپذیرد. تابع فراهم شده در هوک، هر زمان که آرایه مذکور بروزرسانی شده یا تغییر کند، اجرا خواهد شد.
حال شما یک صفحه دارید که ده تصویر تصادفی را از Unsplash دریافت میکند. بیایید به سراغ رندر کردن این تصاویر در یک محفظه با اسکرول بینهایت برویم.
React-infinite-scroll-component یک کامپوننت است که پیشتر آن را وارد کردیم و قابلیت نمایش یک حلقه بارگذاری یا هر عنصر دیگری به عنوان یک جانگهدار، فراخوانی یک تابع برای دریافت دادههای بیشتر وقتی که loader در دیدرس است یا به آن نزدیک میشود، و نمایش هر داده مشخص شدهای را فراهم میکند. در JSX برگشتی Collage و بعد از div دارای کلاس header، تصاویر را با استفاده از این کد در یک کامپوننت اسکرول بینهایت رندر کنید:
<InfiniteScroll
dataLength={images}
next={() => fetchImages(5)}
hasMore={true}
loader={
<img
src="https://res.cloudinary.com/chuloo/image/upload/v1550093026/scotch-logo-gif_jq4tgr.gif"
alt="loading"
/>}
>
<div className="image-grid" style={{ marginTop: "30px" }}>
{loaded ?
images.map((image, index) => (
<UnsplashImage url={image.urls.regular} key={index} />
)): ""}
</div>
</InfiniteScroll>
در کامپوننت InfiniteScroll، ما یک تابع را به پارامتر next منتقل کردیم. این تابع به سادگی تابع fetchImages را فراخوانی کرده، و پارامتر 5 را منتقل میکند که در واقع تعداد تصاویری است که قرار است متعاقبا دریافت شوند. در پارامتر loader، ما یک تصویر را در SX منتقل کردیم تا به عنوان یک جانگهدار بارگذاری عمل کند.
.map() برای تکرار بر روی آرایه images در state استفاده میشود و هر تصویر را با استفاده از کامپوننت UnsplashImage رندر میکند.
گالری را استایلبندی کنید
ما از CSS Grid برای استایلبندی تصاویر دریافت شده استفاده خواهیم کرد. CSS مربوطه را به این صورت ویرایش کنید:
.title {
font-family: 'Carter One';
}
.container {
margin-top: 50px;
text-align: center;
}
.image-grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: minmax(50px, auto);
.image-item:nth-child(5n){
grid-column-end: span 2;
}
img{
display: flex;
width: 100%;
height: 100%;
object-fit: cover;
}
}
این کد یک صفحه کاشیبندی شده با ستونهایی دارای عرض 250px را میسازد تا یک محفظه تصویر کامل پر کند. همچنین ردیفها به گونهای تنظیم شدهاند که یک مقدار حداقلی 50px و یک مقدار حداکثری خودکار را برای تطبیق دادن تصویر مورد نظر داشته باشند. ما از ویژگی grid-column-end بر روی تصاویر به صورت ۵ در میان استفاده کردیم، تا آن تصاویر اندازهای دو برابر تصاویر دیگر داشته باشند.
ویژگی object-fit تضمین میکند که هر فایل با محفظهاش تطابق دارد.
نتیجه گیری
در این پست، ما یک گالری تصاویر را با استفاده از React Hooks ساخته، و همچنین CSS Grid را به کار بردیم. شما میتوانید با این کاشیها بازی کنید و حتی یک صفحه بهتر بسازید.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید