Unsplash سایتی است که می توانید تصاویر رایگان را دانلود کرده و به دلخواه از آن ها استفاده کنید. در این آموزش، ما با استفاده از Unsplash API یک برنامه جستجوی تصویر می سازیم تا به تصاویر آن دسترسی داشته باشیم و هم چنین آن ها را دانلود کنیم.
پیش از شروع بیایید ببینیم برنامه از چه بخش هایی تشکیل شده است:
این پروژه برای مبتدیان است، اما هر کسی که میخواهد مهارتهای خود را تقویت کند، میتواند آن را بخواند. در این آموزش موضوع های زیر را یاد خواهید گرفت:
ایجاد یک برنامه React بسیار آسان است. فقط کافی است به دایرکتوری مورد نظر خود بروید و دستور زیر را در ترمینال وارد کنید:
npx create-react-app image-search-app
اگر مطمئن نیستید که چگونه می توانید یک پروژه React را به درستی ایجاد و راه اندازی کنید، می توانید به راهنمای رسمی در این نشانی مراجعه کنید.
پس از نصب برنامه، npm start را در همان ترمینال اجرا کنید تا localhost:3000 که در آن برنامه React ما میزبانی می شود، راه اندازی شود. ما هم چنین می توانیم تمام تغییرات خود را در آن جا مشاهده کنیم.
در ادامه نیاز داریم که برنامه خود را پاک سازی کنیم. منظور این است که باید فایل ها و کدهایی را که نیاز نداریم را پاک کنیم. در پوشه src به بعضی از فایل ها نیاز نداریم. این پوشه پیش از پاک سازی به شکل زیر است:
پوشه src پس از پاک سازی باید به شکل زیر درآید:
سپس باید فایل های موجود در تصویر بالا را به خاطر تغییرهای پیش آمده ویرایش کنیم. کد زیر را در فایل App.js قرار می دهیم:
import React from "react"; const App = () => { return ( <> <div className="container-fluid mt-4"> <div className="row"> <div className="col-12 d-flex justify-content-center align-items-center input"> <input className="col-3 form-control-sm py-1 fs-4 text-capitalize border border-3 border-dark" type="text" placeholder="Search Anything..." /> <button type="submit" // onClick={Submit} className="btn bg-dark text-white fs-3 mx-3" > Search </button> </div> </div> </div> </> ); }; export default App;
در ادامه فایل index.css را کاملا پاک می کنیم.برای استایل دهی برنامه از bootstrap استفاده می کنیم.برای استفاده از bootstrap کد زیر را در index.html در پوشه public قرار می دهیم.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <title>Image Search Application</title> </head> <body> <div id="root"></div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script> </body> </html>
سپس تغییرهای زیر را در فایل index.js به وجود می آوریم:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import { createRoot } from 'react-dom/client'; const container = document.getElementById('root'); const root = createRoot(container); root.render(<App />);
دو بخش در رابط کاربری برنامه ما وجود دارد:
در قسمت Input یک تگ input داریم که عبارت یا query جستجو را در آن می نویسیم. ما هم چنین یک دکمه با یک کنترل کننده رویداد onClick داریم که عملکرد مسئول واکشی داده ها از API را اجرا می کند.
برنامه را با دستور npm start اجرا می کنیم.تا این جا تصویر برنامه به صورت زیر خواهد بود:
در این مقاله در مورد استایل برنامه صحبت نمی کنیم. به این ترتیب میتوانیم روی بخش React که درک آن ضروریتر است، تمرکز بیشتری داشته باشیم.
بیایید کلیدهای API را از Unsplash for Developer دریافت کنیم. برای دریافت کلید API و سایر جزئیات مراحل زیر را دنبال کنید.ابتدا به این لینک بالا بروید و روی ثبت نام به عنوان توسعه دهنده کلیک کنید.
سپس input های که خواسته شده را پر کنید.
پس از این کار، شما به داشبورد developer (توسعه دهنده) هدایت می شوید. روی New Application کلیک کنید.
از شما خواسته می شود که تمام شرایط نوشته شده در آن جا را بپذیرید. پس هم آن ها را کلیک کنید. سپس برای ادامه روی دکمه Accept terms کلیک کنید.
در مرحله بعد، یک فرم modal مانند شکل زیر ظاهر می شود که در آن باید اطلاعات برنامه مانند نام و توضیحات را بنویسید. سپس روی Create Application کلیک کنید.
اکنون که برنامه ما ایجاد شده است، میتوانیم به کلید دسترسی و کلید مخفی در بخش Keys دسترسی داشته باشیم:
توجه کنید که کلمه Demo در همان ابتدای این صفحه، به ایت معنی است که درخواست ما پذیرفته شده است اما هنوز در حالت توسعه است.در این حالت فقط می توانیم 50 درخواست در ساعت داشته باشیم. اگر از این حد تجاوز کنیم، API ما کار نمی کند و تصاویر بارگیری نمی شوند.
پس از این، به documentation بروید و گزینه "Search Photos by Keyword" را انتخاب کنید.
به بخش Response در پایین بروید و پیوند را مانند تصویر کپی کنید:
حالا هم کلید API خود را داریم و هم API Endpoint بیایید ساخت برنامه خود را ادامه دهیم.
ما از هوک های useState و useEffect در برنامه خود استفاده خواهیم کرد. آنها به ما اجازه میدهند state هایی را که برای دریافت مقدار ورودی لازم است تنظیم کنیم و دادههای مربوط به آن مقدار را در API جستجو کنیم. برای این که هوک ها کار کنند، باید آن ها را در بالای برنامه خود در فایل App.js به این صورت تعریف کنیم:
import React, { useState, useEffect } from "react";
همان طور که در بالا توضیح دادیم، از هوک ها برای استخراج داده ها از API با استفاده از مقدار وارد شده در قسمت input استفاده می کنیم. این مقدار توسط برنامه با استفاده از هوک useState خوانده می شود.
state ها را با استفاده از این هوک برای اهداف خاص تعریف می کنیم. در این برنامه، دو مورد از آن ها را تعریف خواهیم کرد: یکی برای دریافت مقدار از فیلد input و دیگری برای نمایش نتایج واکشی شده از API.
const [img, setImg] = useState(""); const [res, setRes] = useState([]);
دو پارامتر در کد بالا وجود دارد که برای تعریف هوک useState استفاده می شود: یکی از آن ها حالتی است که از آن برای ذخیره مقادیر استفاده می کنیم و دیگری تابعی است که برای به روز رسانی مقادیر state استفاده خواهیم کرد. اطلاعات بیشتر در مورد هوک useState را این جا بخوانید.
state اول را به عنوان یک رشته خالی تعریف کرده ایم زیرا از آن برای ذخیره ورودی از نوار جستجو استفاده می شود.
state دیگر به عنوان یک آرایه خالی مقدار دهی اولیه می شود زیرا داده های واکشی شده از API را ذخیره می کند و سپس آن را در بخش نتیجه ما نشان می دهد.
بهطور پیشفرض، فقط میتوانیم تا 10 داده در هر درخواست دریافت کنیم، اما میتوانیم با استفاده از پارامتر per_page که بعدا در این آموزش مشاهده خواهیم کرد، از آن فراتر برویم.
مرحله بعدی ذخیره مقدار فیلد متن ورودی در state برای img با استفاده از ویژگی value تگ input است. سپس یک کنترل کننده رویداد onChange به آن اضافه می کنیم. این کنترل کننده رویداد onChange() تابعی خواهد داشت که برای به روز رسانی حالت با استفاده از e.target.value استفاده می شود.
<input className="col-3 form-control-sm py-1 fs-4 text-capitalize border border-3 border-dark" type="text" placeholder="Search Anything..." value={img} onChange={(e) => setImg(e.target.value)} />;
اکنون از Unsplash API و کلید دسترسی که در مرحله بالا به دست آورده ایم برای واکشی داده ها و نمایش آن ها در برنامه خود استفاده می کنیم.
برای این کار، دوباره به یک state برای ذخیره دادههای واکشی شده از API که قبلا در بخش بالا تعریف کردهایم نیاز داریم (res برای این منظور به عنوان یک آرایه خالی مقدار دهی اولیه میشود).
روشهای زیادی در جاوا اسکریپت وجود دارد که میتوانیم از آن ها برای واکشی دادهها از یک API استفاده کنیم، اما از روش async-wait استفاده میکنیم. این بسیار سادهترین روش است.
const fetchRequest = async () => { const data = await fetch( `https://api.unsplash.com/search/photos?page=1&query=${img}&client_id=${Access_Key}` ); const dataJ = await data.json(); const result = dataJ.results; console.log(result); setRes(result); }; useEffect(() => { fetchRequest(); }, []);
توجه داشته باشید که ${Access_Key} را نوشته ایم .در این جا باید کلید دسترسی خود را بنویسیم. این مرحله را تکمیل می کنیم تا کلید API خود را ایمن کنیم زیرا هر کسی می تواند از آن سو استفاده کند.
در Unsplash نیز میتوانیم برای تولید اپلیکیشن خود اقدام کنیم و با این کار میتوانیم با تصاویری که Unsplash ارائه میکند آنلاین شویم.
به همین دلیل، همه افراد مجموعه متفاوتی از کلیدهای دسترسی و کلیدهای امنیتی را دریافت می کنند. همیشه بهتر است این کلیدها را از دیگران پنهان کنید تا مورد سو استفاده قرار نگیرد و ما بهای آن را بپردازیم.
در کد بالا، ابتدا دادههای واکشی شده از API را در متغیر data ذخیره کردهایم که سپس برای سادگی به JSON تبدیل میشود. این به ما امکان میدهد دادهها را بخوانیم و مقادیر لازم را استخراج کنیم، که در متغیر dataJ ذخیره میشوند و برای بررسی این که آیا مقدار مورد نیاز خود را دریافت میکنیم یا خیر، کنترل میشوند.
و اگر یکی از نتایج جستجوی بالا را باز کنیم تا ببینیم چه مقادیری برای استخراج وجود دارد:
{ "total": 133, "total_pages": 7, "results": [ { "id": "eOLpJytrbsQ", "created_at": "2014-11-18T14:35:36-05:00", width: 4000, height: 3000, color: "#A7A2A1", blur_hash: "LaLXMa9Fx[D%~q%MtQM|kDRjtRIU", likes: 286, liked_by_user: false, description: "A man drinking a coffee.", user: { id: "Ul0QVz12Goo", username: "ugmonk", name: "Jeff Sheldon", first_name: "Jeff", last_name: "Sheldon", instagram_username: "instantgrammer", twitter_username: "ugmonk", portfolio_url: "http://ugmonk.com/", profile_image: { small: "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=32&w=32&s=7cfe3b93750cb0c93e2f7caec08b5a41", medium: "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=64&w=64&s=5a9dc749c43ce5bd60870b129a40902f", large: "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=128&w=128&s=32085a077889586df88bfbe406692202", }, links: { self: "https://api.unsplash.com/users/ugmonk", html: "http://unsplash.com/@ugmonk", photos: "https://api.unsplash.com/users/ugmonk/photos", likes: "https://api.unsplash.com/users/ugmonk/likes", }, }, current_user_collections: [], urls: { raw: "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f", full: "https://hd.unsplash.com/photo-1416339306562-f3d12fefd36f", regular: "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=92f3e02f63678acc8416d044e189f515", small: "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&s=263af33585f9d32af39d165b000845eb", thumb: "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=8aae34cf35df31a592f0bef16e6342ef", }, links: { self: "https://api.unsplash.com/photos/eOLpJytrbsQ", html: "http://unsplash.com/photos/eOLpJytrbsQ", download: "http://unsplash.com/photos/eOLpJytrbsQ/download", }, }, // more photos ... ], },
بهتر است از این تابع در داخل هوک useEffect استفاده کنید، زیرا در صورت ایجاد هر گونه تغییر در رابط کاربری برنامه، از رندر مجدد داده ها جلوگیری می کند. برای درک عمیق useEffect، این جا را کلیک کنید.
ما از تابع setRes برای به روز رسانی مقدار res که یک آرایه خالی است و درنهای به آرایه ای تبدیل می شود که همه داده های واکشی شده را در فرمت JSON ذخیره می کند، استفاده می کنیم.
قبلا یک تابع onClick را به دکمه در ابتدای برنامه خود در بخش ورودی داده ایم. اکنون زمان آن است که یک تابع برای این کنترل کننده رویداد تعریف کنیم که به محض کلیک روی دکمه جستجو فعال می شود. نام این تابع fetchRequest است که داده ها را واکشی می کند و نتیجه را در قسمت Result به ما نشان می دهد.
const Submit = () => { fetchRequest(); setImg(""); };
در بخش بالا، دادههای واکشی شده از API در یک آرایه ذخیره شده. برای به دست آوردن و نمایش این مقادیر، باید از متد map استفاده کنیم.
<div className="col-12 d-flex justify-content-evenly flex-wrap"> {res.map((val) => { return ( <> <img className="col-3 img-fluid img-thumbnail" src={val.urls.small} alt="val.alt_description" /> </> ); })} </div>;
اگر به عقب برگردیم و پاسخ را به شکل JSON ببینیم، نوع دیگری از اطلاعات را خواهیم یافت: URL هایی که حاوی path تصویر هستند. بنابراین در این جا val.urls.small مسیر واقعی تصویر است و val.alt_description توضیحات alt تصویر است.فیلدهای مختلفی در داخل "url" وجود دارد که داده های متفاوتی را نشان می دهد، مانند:
در این مقاله، ما از Small استفاده خواهیم کرد، اما موارد دیگری نیز وجود دارد که در بالا نشان داده شده است که میتوانیم با آن ها کار کنیم و مورد مناسب خود را پیدا کنیم.
بهطور پیشفرض، تعداد آیتم هایی که میتوان در یک زمان واکشی کرد 10 آیتم است، اما این تعداد بسته به تعداد تصویری که میخواهیم برنامهمان نشان دهد، میتواند افزایش یا کاهش یابد.
برای انجام این کار فقط باید یک پارامتر در پایان فراخوانی API خود (per_page) همان طور که در کد نشان داده شده است اضافه کنیم و آن را برابر با تعداد تصاویری که می خواهیم نشان دهیم قرار دهیم.
const fetchRequest = async () => { const data = await fetch( `https://api.unsplash.com/search/photos?page=1&query=${img}&client_id=${Access_Key}&per_page=20` ); const dataJ = await data.json(); const result = dataJ.results; console.log(result); setRes(result); };
پارامترهای بسیار بیشتری وجود دارد که Unsplash ارائه می دهد.
کد کامل فایل App.js تا این جا به شکل زیر است:
import React, { useState, useEffect } from "react"; const App = () => { const [img, setImg] = useState(""); const [res, setRes] = useState([]); const fetchRequest = async () => { const data = await fetch( `https://api.unsplash.com/search/photos?page=1&query=${img}&client_id=${'P60hRbAd1LyTJpknpt4FwTfKQp8uH-8dJM3DIOTX3is'}` ); const dataJ = await data.json(); const result = dataJ.results; console.log(result); setRes(result); }; useEffect(() => { fetchRequest(); }, []); const Submit = () => { fetchRequest(); setImg(""); }; return ( <> <div className="container-fluid mt-4"> <div className="row"> <div className="col-12 d-flex justify-content-center align-items-center input"> <input className="col-3 form-control-sm py-1 fs-4 text-capitalize border border-3 border-dark" type="text" placeholder="Search Anything..." value={img} onChange={(e) => setImg(e.target.value)} /> <button type="submit" onClick={Submit} className="btn bg-dark text-white fs-3 mx-3" > Search </button> </div> </div> <div className="col-12 mt-4 d-flex justify-content-evenly flex-wrap"> {res.map((val) => { return ( <> <img className="col-3 img-fluid img-thumbnail" src={val.urls.small} alt="val.alt_description" /> </> ); })} </div> </div> </> ); }; export default App;
اگر اکنون در مورد فلگ ها جستجوی سریع انجام دهیم، تصاویر خود را دریافت خواهیم کرد. اما هنوز برخی از مشکلات وجود دارد که باید برطرف شود. یکی از آن ها خطایی است که در کنسول دریافت می کنیم.
برای رفع این مشکل، یک کلید منحصر به فرد را با استفاده از شناسه تصویر به هر فرزند ارسال کنید. این کلید prop به صراحت هویت هر فرزند را در یک لیست به React می گوید. این کلید همچنین از نابودی state فرزندان بین رندرها جلوگیری می کند.
<div className="col-12 d-flex justify-content-evenly flex-wrap"> {res.map((val) => { return ( <> <img key={val.id} className="col-3 img-fluid img-thumbnail" src={val.urls.small} alt="val.alt_description" /> </> ); })} </div>;
اگر برنامه را باز کنیم و در input به عنوان مثال کلمه cat را بنویسیم با تصویر زیر روبه رو خواهیم شد:
کد کامل این برنامه را می توانید از این نشانی دانلود کنید.
در این آموزش، ما یک برنامه جستجوی عکس در React با استفاده از Unsplash API ایجاد کرده ایم. در حین ساختن برنامه، موارد زیادی مانند نحوه استفاده از هوک های React برای دریافت دادهها از یک API و استفاده از آن برای نمایش تصاویر در برنامه خود بحث کردیم.
کارهای بیشتری وجود دارد که می توانید در این برنامه انجام دهید. به عنوان مثال، میتوانیم یک دکمه تصادفی برای نمایش تصاویر تصادفی اضافه کنیم، یک چک باکس برای جابهجایی بین جستجوی عکسها یا کاربرانی که آنها را بر اساس ترجیح کاربر ارسال کردهاند ایجاد کنیم، یک اسکرول بینهایت برای نمایش تصاویر بیشتر اضافه کنیم و موارد دیگر.
منبع: وب سایت freecodecamp
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.